Dynamic Query Builder для ASP.Net-MVC - Использование jQuery QueryBuilder, DataTables и динамического linq-query-builder - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь выполнить следующие задачи:

  1. Создать визуальное выражение / построитель запросов для ASP.NET-MVC.
  2. Передать полученный запрос в DataTables.

Этот вопрос касается Задачи 1, потому что я застрял там.Я опубликовал задачу 2, чтобы предоставить дополнительную справочную информацию.

Для выполнения задачи 1 я использую jQuery QueryBuilder - плагин jQuery для создания удобных для пользователя запросов.На сайте QueryBuilder есть список для .NET в разделе Backends (https://querybuilder.js.org/#backends). Они рекомендуют использовать динамический-linq-query-builder от Castle-it (https://github.com/castle-it/dynamic-linq-query-builder).

* 1016)* Вот моя проблема:

Кажется, что динамический-linq-запрос-построитель построен на статических классах. Я хочу получить данные из моей базы данных, но из моих онлайн-исследований я невозможность инициировать dbcontext внутри статического класса.

Динамический запрос-linq предоставляет класс PersonBuilder для десериализации данных JSON, и они включают строку TestData:

 public static class PersonBuilder
            {
                public static List<PersonRecord> GetPeople()
                {
                    var result = new List<PersonRecord>();

                    var testData = TestData;

                    var personRecords = JsonConvert.DeserializeObject<List<PersonRecord>>(testData);

                    return personRecords;

                }

                private static string TestData
                {
                    get
                    {
                        return @"
                                [
            {
                ""FirstName"": ""Jane"",

                ""LastName"": ""Hansen"",
                ""Birthday"": ""1969-12-31T16:00:00-08:00"",
                ""Address"": ""P.O. Box 492, 4607 Tempus, Rd."",
                ""City"": ""Polatlı"",
                ""State"": ""Ankara"",
             ...
             ...
             ...

Затем в HomeControllerони используют следующее для фильтрации запроса:

[HttpPost]
public JsonResult Index(FilterRule obj)
{
    var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
    var people = PersonBuilder.GetPeople().BuildQuery(obj).ToList();

    return Json(people);


}

А вот их реализация QueryBuilder и логика jQuery для считывания результатов.

  <script type="text/javascript">
    $(function() {
        // Handler for .ready() called.
        var tableData = [];

        var filterDefinition = @Html.Raw(ViewBag.FilterDefinition);
        var customFilters = {
            condition: 'AND',
            rules: []
        };
        var jqueryQueryBuilder = $('#jquery-query-builder');
        var jqueryQueryBuilderDom = jqueryQueryBuilder.queryBuilder({
            plugins: ['bt-tooltip-errors', 'filter-description'],
            //allow_groups: 0,
            allow_empty: true,
            filters: filterDefinition,
            rules: customFilters,
            icons: {
                add_group: 'fa fa-plus-square',
                add_rule: 'fa fa-plus-circle',
                remove_group: 'fa fa-minus-square',
                remove_rule: 'fa fa-minus-circle',
                error: 'fa fa-exclamation-triangle',
                sortable: 'fa fa-exclamation-triangle'
            }
        });

        var convertArraysToCommaDelimited = function(obj) {
            if (obj != null) {
                if (obj.hasOwnProperty("value")) {
                    if( Object.prototype.toString.call( obj.value ) === '[object Array]' ) {
                        obj.value = obj.value.join(", ");
                    }
                }
                if (obj.hasOwnProperty("rules") && obj.rules != null) {
                    for (var i = 0; i < obj.rules.length; i++) {
                        convertArraysToCommaDelimited(obj.rules[i]);
                    }
                }
            }
        }
        var getRules = function() {
            try {
                var res =  jqueryQueryBuilder.queryBuilder('getRules');
                convertArraysToCommaDelimited(res);
                return res;
            } catch (ex) {
                //console.log(ex);
                return null;
            }
        }

        var buildTable;
        var filterData = function() {

            $.ajax({
                type: 'POST',
                url: "../Home/Index",
                data: JSON.stringify(getRules()),
                success: function (returnPayload) {
                    tableData = returnPayload;
                    buildTable();
                    console && console.log ("request succeeded");
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console && console.log ("request failed");
                },
                dataType: "json",
                contentType: "application/json",            
                processData: false,
                async: true
            });
        }



        $('#applyFilter').on('click', function() {
            filterData();
        });
        buildTable = function() {
            var tbody = $('#data-table tbody'),
                props = ["FirstName", "LastName", "Birthday", "Age", "Address", "City", "State", "ZipCode"];
            tbody.empty();
            $.each(tableData, function(i, reservation) {
                var tr = $('<tr>');
                $.each(props, function(i, prop) {
                    $('<td>').html(reservation[prop]).appendTo(tr);  
                });
                tbody.append(tr);
            });
        };

        filterData();

    });

</script>

Вы заметите, что они 'я создал функцию buildTable. Позже я хотел бы заменить ее реализацией DataTable.

Что я пробовал:

Я пытался инициировать dbcontext с помощьюLINQ в классе PersonBuilder.Проблема в том, что этот класс был статическим.Я просто удалил статическое определение класса PersonBuilder.Вот моя реализация:

public List<PersonRecord> GetPeople()
        {
            IQueryable<PersonRecord> query = DbContext.PersonRecord;


            var data = query.Select(asset => new Asset
            {
                data1 = PersonRecord.data1,
                data2 = PersonRecord.data2,
                ...
                ...

            }).ToList();

            return data;
        }

Проблема, с которой я сталкиваюсь, заключается в том, что HomeController теперь выдает следующую ошибку:

CS0120: Ссылка на объект требуется для нестатическогополе, метод или свойство 'member'

В следующей строке:

var people = PersonBuilder.GetPeople().BuildQuery(obj).ToList();

Не совсем уверен, как обойти это, так как кажется, что вся библиотека построена со статическимклассы?

Что вы, ребята, думаете?

1 Ответ

0 голосов
/ 21 ноября 2018

Основная проблема в том, что вы определяете GetPeople() как нестатический метод внутри класса PersonBuilder, который помечен как static.Как отмечено в документации MSDN , статические классы должны содержать только статические члены, включая статические методы (см. Причину здесь ).

Ошибка CS0120 указывает, что вы должны использовать либо статический класс со статическим методом, либо инстанцированный конструктор нестатического класса в качестве объекта.Если вы хотите использовать нестатический метод, класс не должен быть помечен как static, также перед созданием метода должен быть создан экземпляр класса:

public class PersonBuilder
{
    public List<PersonRecord> GetPeople()
    {
        IQueryable<PersonRecord> query = DbContext.PersonRecord;

        var data = query.Select(asset => new Asset
        {
           data1 = PersonRecord.data1,
           data2 = PersonRecord.data2,
           // other stuff

        }).ToList();

        return data;
    }
}

Использование

[HttpPost]
public JsonResult Index(FilterRule obj)
{
    var jsonSerializerSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
    var personBuilder = new PersonBuilder(); // add constructor initialization first
    var people = personBuilder.GetPeople().BuildQuery(obj).ToList();

    return Json(people);
}

Проблема, связанная с данной:

Как избежать ошибки CS0120 в моем коде?

...