2011-12-15 41 views
2

動態添加謂詞在Ado.NET的世界,我可以像下面Linq中

Void SomeMethod(bool flag) 
{ 
String Query = 「 SELECT * FROM Products WHERE CategoryID = 125」; 
If (flag == true) 
    Query += 「 AND Price > 25」 
.... 
} 

在LINQ的世界中的代碼,我可以動態地添加這些額外的過濾器?

+1

http://www.albahari.com/nutshell/predicatebuilder.aspx – 2011-12-15 22:03:40

回答

5
if (someFlag) 
    query = query.Where(p => p.Price > 25); 
+0

所以查詢將已經包含thr的結果爲CateogryID意思是在這種情況下,我將數據庫兩次? – 2011-12-15 22:02:57

+0

否,直到您實際獲取結果纔會觸及數據庫 – Guillaume86 2011-12-15 22:03:50

7
var query = context.Products.Where(p => p.CategoryID == 125); 
if (flag) 
    query = query.Where(p => p.Price > 25); 
0
var data = from p in context.Products 
      where (flag == false && p.CategoryID == 125) 
       || (flag == true && p.CategoryID == 125 && p.Price > 25) 
      select p; 
0
private void GetData(bool flag) 
    { 
     var query = from p in db.products 
        where p.CategoryId == 125 
        select p; 

      if(flag) 
     query = query.Where(o => o.Price > 25); 
    } 
3

你可以欺騙和使用標誌作爲查詢的一部分。

var query = from p in Products 
      where p.CategoryID == 125 
       && (!flag || p.Price > 25) 
      select p 
      ; 

如果你傳遞額外的標準,你可以將它們應用到枚舉,並得到一個新的枚舉,如SLaks和Wiktor的Zychla提及。該查詢將不會得到解決,直到調用ToList

IEnumerable<Product> GetProducts(params Func<Product, bool>[] criteria) 
{ 
    var query = Products.Where(p => p.CategoryID == 125); 
    foreach(criterion in criteria) 
    { 
     query = query.Where(criterion); 
    } 
    return query; 
} 

// ... 

var notFiltered = someObject.GetProducts().ToList(); 
var filtered = someObject 
    .GetProducts(
     p => p.Price > 25, 
     p => p.AverageReviewScore > 4 
     ) 
    .ToList(); 

請注意,如果你這樣做與LINQ到實體,而不是LINQ到對象,這可能無法正常工作爲好,或者你至少必須返回IQueryable而不是IEnumerable。還沒有嘗試過:)