2009-01-29 103 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表达式语法创建的过滤器。