2009-01-29 153 views
3

我在構建應用程序的一部分,該應用程序圍繞從數據庫中提取有關事務的信息。由於數據的性質,表格中有許多列要過濾。我有一個包含15個字段的篩選器選擇框,我希望能夠爲LINQ語句構建一個where子句。有趣的部分來自於我希望某些字段爲空的情況。例如,我希望能夠在任何或所有的過濾器:LINQ,查詢中的大型過濾器

  • 交易類型
  • 響應代碼
  • 交易金額
  • 還有更多

我可以建立一個謂語看起來像

Func<Transaction, bool> pred = t => t.ResponseCode == ResponseCode && t.TransactionType == TransactionType && t.TransactionAmount > 100.00; 

Bu噸爲了能夠選擇哪些字段謂詞包括我concatenating the predicates在一起:

Func<Transaction, bool> pred = t => true; 
if(ResponseCode != null) 
    pred.AndAlso(t => t.ResponseCode == ResponseCode); 
// Rinse and repeat 

然後傳遞一個謂詞的LINQ語句的where子句。

這種方式完全符合我的要求,但相當複雜。有沒有其他的方法來做到這一點?

更新: 感謝大法官的意見。我沒有使用LINQ to SQL,我使用LINQ對來自存儲庫的對象集合。你將如何以編程方式構建表達式過濾器?

+0

如果你使用LinqToObjects(上System.Linq.Enumerable方法),你不需要擔心表達< Func >。請使用Func 。 – 2009-01-29 21:31:21

回答

8
  • 在動態SQL ...由於您只有一個WHERE子句 - 您必須將謂詞連接爲AND。
  • 在linq查詢構造中,您可以根據需要獲取儘可能多的WHERE子句。當它翻譯查詢時,Linq會和你一起爲你。

例子:

IQueryable<Transaction> query = db.Transactions; 

if (filterByTransactionType) 
{ 
    query = query.Where(t => t.TransactionType == theTransactionType); 
} 
if (filterByResponseCode) 
{ 
    query = query.Where(t => t.ResponseCode == theResponseCode); 
} 
if (filterByAmount) 
{ 
    query = query.Where(t => t.TransactionAmount > theAmount); 
} 

又如:

List<Expression<Func<Transaction, bool>>> filters = GetFilterExpressions(); 

IQueryable<Transaction> query = db.Transactions; 
filters.ForEach(f => query = query.Where(f)); 
0

首先,您需要使用Expression<Func<Transaction, bool>>來執行LINQ-to-SQL(這就是您要使用的,與LINQ不一樣)。

其次,您可以使用System.Linq.Expression命名空間以編程方式構建Expression<Func<Transaction, bool>>

您將無法使用LINQ本身使用編程式構建的表達式來查詢數據庫。您不需要使用查詢運算符,而需要使用查詢擴展方法:例如,您將需要使用db.People.Where(p => p.Age > 50)而不是from p in db.People where p.Age > 50 select p.Name。您可以使用此樣式添加過濾器:db.People.Where(myFilter),其中myFilter = new Expression<Func<Person, bool>>(p => p.Age > 50)。在你的情況下,myFilter將是你的程序化構建過濾器,而不是使用lambda表達式語法創建的過濾器。