2013-01-16 139 views
2

我已经看到了一些旧的帖子,但无法弄清楚如何实现这一点,请帮助一个例子。如何动态创建Linq查询

我在DataTable上运行一个查询来分组所有的列。数列只会被称为运行时,因此我需要动态地构建查询。

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

我需要为n number of columns动态构建上述查询。

请解释如何通过循环遍历列列表并构建Lambda表达式来构建ParameterExpression。

+0

你能在我的答案提供反馈?我觉得应该是足够好回答或浏览你想要的解决方案。 –

回答

0

总之:关于如何实现这个目标有不同的方法。困难的方法是通过使用表达式来建立Func和Predicates的组合。更简单的办法是图书馆的利用率 - 下面提到LINQ Dynamic Query Library

解决方案#1:这里是一个很好的起点看 - Building LINQ Queries at Runtime in C#

解决方案2:你应该也能通过使用Linq Dynamic Query来实现此目的,因为它为此构建 - Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)

0

我多次看到这个问题,所以我决定创建一个博客,而不是从C#中操纵数据。我使用动态SQL从SQL数据库级完成了大量的工作。

Here is the link。希望这可以帮助。

0

我有一种情况,我需要为查询的左侧和右侧动态生成LINQ查询。换句话说,Where(“some property == some value”)。我在LINQPad中玩弄了PredicateBuilder,并尝试了其他一些东西,但最终LINQ动态查询库(System.Linq.Dynamic)使这项任务变得非常简单。

没有经过所有的细节,我有一个方法,它需要在MVC页面上的jqGrid上过滤和排序项目的参数。名为QueryOptions的对象包含各种查询设置。 Data.ImportDataSearchView是绑定到后端数据库视图的实体框架实体。

过滤器表达式是通过调用建立:

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

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

然后数据被检索如下建立表达串后:

 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(); 

下面的options.FilterExpression字符串是t通过该方法BuildFilterExpression拼凑成一个好的,简单谓词字符串为重稀土LINQ搜索条件字段where子句:

“BmpName.Trim()ToLower将()包含(\” 作物\“)& & DataProviderId。降低()。等于(\“123 \”)& & StatusId == 1"