0

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

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

这个问题是关于任务 1 的,因为那是我卡住的地方。我已发布任务 2 以提供更多背景信息。

为了实现任务 1,我使用了 jQuery QueryBuilder - 一个 jQuery 插件来创建用户友好的查询。在 QueryBuilder 网站的后端部分 ( https://querybuilder.js.org/#backends ) 下有一个 .NET 列表。他们建议使用 Castle-it 的 dynamic-linq-query-builder ( https://github.com/castle-it/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();

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

你们有什么感想?

4

1 回答 1

1

主要问题是您在标记为的类中定义GetPeople()为非静态方法。如MSDN 文档中所述,静态类必须仅包含静态成员,包括静态方法(请参阅此处的原因)。PersonBuilderstatic

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 错误?

于 2018-11-21T03:07:13.163 回答