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

时间:2018-11-20 16:00:48

标签: c# asp.net-mvc linq datatables jquery-query-builder

我正在尝试完成以下任务:

  1. 为ASP.NET-MVC创建可视表达式/查询生成器。
  2. 将结果查询传递到DataTables。

这个问题与任务1有关,因为这就是我遇到的问题。我已发布任务2以提供更多背景信息。

要完成任务1,我正在使用jQuery QueryBuilder-一个jQuery插件来创建用户友好的查询。在QueryBuilder网站上,“后端​​”部分(https://querybuilder.js.org/#backends)下有一个.NET列表。他们建议使用Castle-it(https://github.com/castle-it/dynamic-linq-query-builder)的dynamic-linq-query-builder。

这是我的问题:

dynamic-linq-query-builder似乎都是用静态类构建的。我想从数据库中检索数据,但是从在线研究中,我无法在静态类中启动dbcontext。

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"",
             ...
             ...
             ...

然后在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实现代替它。

我尝试过的事情:

我尝试在PersonBuilder类中使用LINQ初始化dbcontext。问题是此类是静态的。我只是删除了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:非静态字段需要对象引用,   方法或属性“成员”

在以下行:

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

不太确定如何解决此问题,因为似乎整个库都是使用静态类构建的?

你们怎么看?

1 个答案:

答案 0 :(得分:0)

主要问题在于,您正在GetPeople()类中将PersonBuilder定义为非静态方法,并将其标记为static。如MSDN documentation中所述,静态类必须仅包含静态成员,包括静态方法(请参见原因here)。

CS0120 error指示您应该使用带有静态方法的静态类,或者使用非静态类的实例化构造函数作为对象。如果要使用非静态方法,则不应将类标记为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);
}

相关问题:

How shouldi avoid the CS0120 error in my code?