简体   繁体   English

如何动态构建Linq查询

[英]How to build a Linq Query Dynamically

I have see a few old post but cannot figure out how to achieve this, Please help with an example. 我看到了一些旧帖子,但无法弄清楚如何实现这一点,请提供示例。

I am running a query on a DataTable to group all the columns. 我在DataTable上运行查询以对所有列进行分组。 The number columns will only be known as runtime hence I need to build the query dynamically. 数字列将仅称为运行时,因此我需要动态构建查询。

var newGroup = from row in dataTable.AsEnumerable() 
group row by new { ID = row.Field<string>("column1"), group1 = row.Field<string>("column2") };

I need to build the above query dynamically for n number of columns . 我需要为n number of columns动态构建以上查询。

Please explain how can I build the ParameterExpression by looping over the columns list and build a Lambda expression. 请解释如何通过遍历列列表并构建Lambda表达式来构建ParameterExpression。

In short: There are different ways on how to achieve this. 简而言之:如何实现此目标有不同的方法。 The hard way is to build the combination of Func and Predicates by using the expressions. 困难的方法是通过使用表达式来构建Func和谓词的组合。 The more easier way is the utilization of library - LINQ Dynamic Query Library mentioned below: 更简单的方法是利用库-下文提到的LINQ Dynamic Query Library

Solution # 1: Here is a good start point to look - Building LINQ Queries at Runtime in C# 解决方案#1:这是一个很好的起点- 在C#中的运行时构建LINQ查询

Solution # 2: you should be also able to do this by using Linq Dynamic Query , as it build for this purposes - Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library) . 解决方案2:您还应该能够使用Linq Dynamic Query来实现此目的,因为它是为此目的而构建的- 动态LINQ(第1部分:使用LINQ动态查询库)

I've saw this question many times so I decided to create a blog but instead of manipulating the data from C#. 我已经多次看到这个问题,所以我决定创建一个博客,而不是操纵来自C#的数据。 I've done the heavy lefting from the SQL database level by utilizing dynamic SQL. 我已经利用动态SQL在SQL数据库级别上完成了很多工作。

Here is the link . 这是链接 Hope this helps. 希望这可以帮助。

I had a situation where I needed to produce a LINQ query dynamically for both the left side and right side of the query. 我遇到一种情况,我需要为查询的左侧和右侧动态生成LINQ查询。 So in other words, Where("some property == some value"). 所以换句话说,Where(“ some property == some value”)。 I played around with PredicateBuilder from the guys at LINQPad, and tried a few other things, but in the end the LINQ Dynamic Query Library (System.Linq.Dynamic) made this task very simple. 我在LINQPad的团队中与PredicateBuilder一起玩耍,并尝试了其他一些方法,但最后LINQ动态查询库(System.Linq.Dynamic)使此任务非常简单。

Without going through all the details, what I have is a method that takes parameters for filtering and sorting items on a jqGrid on an MVC page. 在不进行所有详细介绍的情况下,我所拥有的是一种方法,该方法采用参数来对MVC页面上的jqGrid上的项目进行过滤和排序。 An object called QueryOptions holds various query settings. 名为QueryOptions的对象拥有各种查询设置。 Data.ImportDataSearchView is the Entity Framework entity that is tied to a database view on the backend. Data.ImportDataSearchView是绑定到后端数据库视图的Entity Framework实体。

The filter expression is build up by calling: 过滤器表达式是通过调用以下命令构建的:

        options.FilterExpression += filterList.BuildFilterExpression<Data.ImportDataSearchView>();

Part of BuildFilterExpression is as follows: BuildFilterExpression的一部分如下:

    public string BuildFilterExpression<T>()
    {
        var type = typeof(T);
        var exp = string.Empty;

        foreach (Filter filter in this)
        {
            var typeName = filter.DataType.ToLower();

            // Skip if no values
            if (!filter.Values.Any())
                continue;

            switch (typeName)
            {
                case "string":
                    // html decode string and escape single quotes
                    var stringVal = System.Web.HttpUtility.HtmlDecode(filter.Values[0]);
                    stringVal = stringVal.Replace("'", "''");

                    if (filter.Operator == Enums.FilterOperator.CONTAINS)
                        exp += string.Format("{0}.Trim().ToLower().Contains(\"{1}\")", filter.Attribute, stringVal.Trim().ToLower());

                    else if (filter.Operator == Enums.FilterOperator.DOES_NOT_EQUAL)
                        exp += string.Format("!{0}.ToLower().Equals(\"{1}\")", filter.Attribute, stringVal.ToLower());

                    else if (filter.Operator == Enums.FilterOperator.DOES_NOT_CONTAIN)
                        exp += string.Format("!{0}.Trim().ToLower().Contains(\"{1}\")", filter.Attribute, stringVal.Trim().ToLower());

                    else if (filter.Operator == Enums.FilterOperator.ENDS_WITH)
                        exp += string.Format("{0}.Trim().ToLower().EndsWith(\"{1}\")", filter.Attribute, stringVal.Trim().ToLower());

                    else if (filter.Operator == Enums.FilterOperator.EQUALS)
                        exp += string.Format("{0}.ToLower().Equals(\"{1}\")", filter.Attribute, stringVal.ToLower());

                    else if (filter.Operator == Enums.FilterOperator.STARTS_WITH)
                        exp += string.Format("{0}.Trim().ToLower().StartsWith(\"{1}\")", filter.Attribute, stringVal.Trim().ToLower());

                    break;

                //case "select": -- for dropdowns
                //case "datetime": -- for dates, etc. etc.

            // add spaces around expression
            exp = string.Format(" {0} ", exp);

            // add and/or to expression
            if (this.IndexOf(filter) != this.Count() - 1)
                exp += string.Format(" {0} ", ExpressionType.ToLower() == "and" ? "&&" : "||");
        }

        return exp;
    }

And then data was retrieved as follows, after building up the expression string: 然后,在构建了表达式字符串之后,按以下方式检索数据:

        options.OrderBy = string.IsNullOrEmpty(sortIndex) ? "TrackingId asc" : string.Format(" {0} {1} ", sortIndex, sortOrder);

        var db = new Data.BmpDB();
        var list = string.IsNullOrEmpty(options.FilterExpression)
            ? db.ImportDataSearchViews.OrderBy(options.OrderBy).ToList()
            : db.ImportDataSearchViews.Where(options.FilterExpression).OrderBy(options.OrderBy).ToList();

The options.FilterExpression string below is an example of three search criteria fields pieced together by the method BuildFilterExpression into a nice, simple predicate string for the LINQ where clause: 下面的options.FilterExpression字符串是通过BuildFilterExpression方法将三个搜索条件字段拼凑成LINQ where子句的漂亮,简单谓词字符串的示例:

"BmpName.Trim().ToLower().Contains(\\"crops\\") && DataProviderId.ToLower().Equals(\\"123\\") && StatusId == 1" “ BmpName.Trim()。ToLower()。包含(\\” crops \\“)&& DataProviderId.ToLower()。Equals(\\” 123 \\“)&& StatusId == 1”

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

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