2010-01-08 104 views
0

我知道網上有很多這樣的例子,但我似乎無法得到這個工作。LINQ到對象的動態where子句

讓我試着設置它,我有一個自定義對象列表,我需要對一系列值進行限制。

我有一個基於UI上的某些操作而改變的排序變量,並且我需要根據該操作以不同方式處理該對象。

這是我的目標:

MyObject.ID - Just an identifier 
MyObject.Cost - The cost of the object. 
MyObject.Name - The name of the object. 

現在我需要基於成本範圍內篩選這一點,所以我將與此類似,考慮到我可以用我的底部或者被限制兩個屬性。

var product = from mo in myobject 
       where mo.Cost <= 10000 

var product = from mo in myobject 
       where mo.Name equals strName 

現在我已經在我的項目動態LINQ,但我沒有搞清楚如何得到它的實際工作,因爲當我做一些我的例子只能得到:

Func<Tsourse>bool> predicate 

作爲選項。

更新: 我試圖找到一個解決方案,可以幫助我物化我的代碼,因爲現在它是一個很大的複製和粘貼我的LINQ查詢。

更新2: 是否存在之間存在明顯的性能差異:

var product = from mo in myobject 
... a few joins ... 
where mo.Cost <= 10000 

var product = (from mo in myobject 
... a few joins ...) 
.AsQueryable() 
.Where("Cost > 1000") 
+1

不其中mo.Cost <= 10000 || mo.Name等於strName工作? –

+0

您是否在''using'中添加了'System.Linq.Dynamic'? –

回答

2

也許不會直接回答你的問題,但DynamicQuery在這裏是不必要的。如果條件是相互排斥的,然後只需更改第二ifelse if

public IEnumerable<MyObject> GetMyObjects(int? maxCost, string name) 
{ 
    var query = context.MyObjects; 
    if (maxCost != null) 
    { 
     query = query.Where(mo => mo.Cost <= (int)maxCost); 
    } 
    if (!string.IsNullOrEmpty(name)) 
    { 
     query = query.Where(mo => mo.Name == name); 
    } 
    return query; 
} 

:你可以寫這個查詢的。

我使用這個模式所有的時間。 「動態查詢」的真正含義是將純SQL與Linq結合在一起;它在飛行中產生條件並不能真正幫助你。

+0

我想只是使用那些'where'作爲例子,我認爲他意味着他可能有很多不同的過濾器。 –

+1

@Stan:無論有多少種不同的過濾器都無關緊要,您可以無限期地以這種方式繼續構建表達式。在引擎蓋下,這正是編寫一個正則表達式'from x in y'查詢表達式,但沒有條件。 DynamicQuery僅用於需要將查詢編寫爲字符串的情況;如果你使用lambda表達式,你不需要它。 – Aaronaught

+0

@Aaronaught,你不可能繼續寫很多不同的過濾器,因爲可能有大量的變化。假設你有5個字段,這是超過200個可能的濾波器組合。 –

1

通過ScottGu

Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)

01閱讀DLINQ這個偉大的職位

你會需要這樣的東西

var product = myobject.Where("Cost <= 10000"); 
var product = myobject.Where("Name = @0", strName); 

如果您下載您需要找到Dynamic.cs文件樣本中的樣本。您需要將此文件複製到您的項目中,然後將 using System.Linq.Dynamic;添加到您正在嘗試使用Dynamic Linq的課程中。

編輯:要回答您的編輯。是的,當然有性能差異。如果你事先知道過濾器的變化,那麼我會建議不使用DLINQ來寫出它們。

您可以像這樣創建自己的擴展方法。

public static class FilterExtensions 
    { 
     public static IEnumerable<T> AddFilter<T,T1>(this IEnumerable<T> list, Func<T,T1, bool> filter, T1 argument) 
     { 
      return list.Where(foo => filter(foo, argument)); 
     } 
    } 

然後創建您的過濾器方法。現在

 public bool FilterById(Foo obj, int id) 
     { 
      return obj.id == id; 
     } 

     public bool FilterByName(Foo obj, string name) 
     { 
      return obj.name == name; 
     } 

你可以在一個IEnumerable<Foo>很容易使用。

List<Foo> foos = new List<Foo>(); 
    foos.Add(new Foo() { id = 1, name = "test" }); 
    foos.Add(new Foo() { id = 1, name = "test1" }); 
    foos.Add(new Foo() { id = 2, name = "test2" }); 

    //Example 1 
    //get all Foos's by Id == 1 
    var list1 = foos.AddFilter(FilterById, 1); 

    //Example 2 
    //get all Foo's by name == "test1" 
    var list2 = foos.AddFilter(FilterByName, "test1"); 

    //Example 3 
    //get all Foo's by Id and Name 
    var list1 = foos.AddFilter(FilterById, 1).AddFilter(FilterByName, "test1"); 
+0

閱讀我的問題,我說我在我的項目中有這個問題,但無法實際工作。 –

+0

這是因爲您需要實際使用DLINQ擴展方法。 –

+0

這是什麼意思?如果我明白我做錯了什麼,我不會在這裏問。 –

1
using System.Linq; 

var products = mo.Where(x => x.Name == "xyz"); 

var products = mo.Where(x => x.Cost <= 1000); 

var products = mo.Where(x => x.Name == "xyz" || x.Cost <= 1000);