2013-01-16 130 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"