简体   繁体   English

ASP.Net-MVC的动态查询生成器-使用jQuery QueryBuilder,DataTables和dynamic-linq-query-builder

[英]Dynamic Query Builder for ASP.Net-MVC - Using jQuery QueryBuilder, DataTables, and dynamic-linq-query-builder

I'm trying to accomplish the following Tasks: 我正在尝试完成以下任务:

  1. Create a visual expression/ query builder for ASP.NET-MVC. 为ASP.NET-MVC创建可视表达式/查询生成器。
  2. Pass the resulting query to DataTables. 将结果查询传递给DataTables。

This question is about Task 1 as that's where I'm stuck. 这个问题与任务1有关,因为这就是我遇到的问题。 I have posted Task 2 to provide more background information. 我已经发布了任务2,以提供更多背景信息。

To achieve Task 1 I'm using the jQuery QueryBuilder - a jQuery plugin to create user friendly queries. 为了实现任务1,我使用jQuery QueryBuilder-一个jQuery插件来创建用户友好的查询。 On the QueryBuilder website there is a listing for .NET under the Backends section ( https://querybuilder.js.org/#backends ). 在QueryBuilder网站上,“后端​​”部分( https://querybuilder.js.org/#backends )下有一个.NET列表。 They recommend to use the dynamic-linq-query-builder by Castle-it ( https://github.com/castle-it/dynamic-linq-query-builder ). 他们建议使用Castle-it( https://github.com/castle-it/dynamic-linq-query-builder )的dynamic-linq-query-builder。

Here is my issue: 这是我的问题:

The dynamic-linq-query-builder all seems to be built with static classes. dynamic-linq-query-builder似乎都是用静态类构建的。 I want to retrieve the data from my database but from my research online I'm not able to initiate a dbcontext within a static class. 我想从数据库中检索数据,但是从在线研究中,我无法在静态类中启动dbcontext。

Dynamic-linq-query provides a PersonBuilder class to deserialize a JSON data and they include a TestData string: Dynamic-linq-query提供了一个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"",
             ...
             ...
             ...

Then in the HomeController they are using the following to filter the query: 然后在HomeController中,他们使用以下内容过滤查询:

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

    return Json(people);


}

And here is their QueryBuilder implementation and jQuery logic to read out the results. 这是他们的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>

You'll notice that they've created a buildTable function. 您会注意到他们已经创建了一个buildTable函数。 Later I would like to replace this with a DataTable implementation. 稍后,我想用DataTable实现代替它。

What I've tried: 我试过的

I have tried to initiate a dbcontext with LINQ in the PersonBuilder class. 我试图在PersonBuilder类中使用LINQ启动dbcontext。 The issue is that this class was static. 问题是此类是静态的。 I simply removed the static definition of the PersonBuilder class. 我只是删除了PersonBuilder类的静态定义。 Here is my implementation: 这是我的实现:

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;
        }

The issue I'm experiencing is that the HomeController is now throwing the following error: 我遇到的问题是HomeController现在抛出以下错误:

CS0120: An object reference is required for the nonstatic field, method, or property 'member' CS0120:非静态字段,方法或属性“成员”需要对象引用

At the following line: 在以下行:

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

Not quite sure how to get around this since it seems the entire library is built with static classes? 由于似乎整个库都是使用静态类构建的,因此不太确定如何解决此问题?

What do you guys think? 你们有什么感想?

The main problem is that you're defining GetPeople() as non-static method inside PersonBuilder class which marked as static . 主要问题是您要在PersonBuilderGetPeople()定义为非静态方法,该方法标记为static As noted in MSDN documentation , static classes must contain only static members, including static methods (see the reason here ). MSDN文档中所述 ,静态类必须仅包含静态成员,包括静态方法(请参见此处的原因)。

The CS0120 error indicates that you should use either static class with static method, or non-static class' instantiated constructor as object. CS0120错误表明您应该使用带有静态方法的静态类,或者将非静态类的实例化构造函数用作对象。 If you want to use non-static method, the class should not marked as static , also the class constructor must be instantiated first before the method can be accessed: 如果要使用非静态方法,则不应将类标记为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;
    }
}

Usage 用法

[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);
}

Related issue: 相关问题:

How shouldi avoid the CS0120 error in my code? 如何避免代码中的CS0120错误?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM