7

在整个应用程序的许多不同查询中出现的一组特定标准已经慢慢变得更加复杂。为避免重复此代码,我想将这些条件拆分为一个方法,该方法将条件作为表达式返回,然后可以在必要时应用:

public Expression<Func<Invoice, bool>> GetComplexPredicate()
{
    // complex predicate is returned as an Expression:
    return c => ...
}

像这样重用:

var result = repository.Invoice.Where(GetComplexPredicate())

但是,下面的语句不会编译,因为c.Invoice只是一个ICollection

var result = repository.Customer
    .Where(c => c.Country == "US" && c.Invoice.Any(GetComplexPredicate()))

是否可以以任何方式使用这样的表达式?

4

1 回答 1

7

这个问题有两个部分:

如何在 L2E 查询内的导航属性上使用谓词表达式?

L2E 允许在查询中使用AsQueryable扩展方法。这意味着我能够将ICollection转换为IQueryable并应用谓词表达式。到目前为止,一切都很好。但是,它可能会编译,但仍不会运行,因为 L2E 不知道如何处理来自 GetComplexPredicate 方法的预定义表达式。这导致我们:

如何将几个单独的谓词表达式组合成一个?

非常有用的LINQKit可以使用PredicateBuilder轻松地将多个谓词组合成一个表达式。使用 LINQKit 中的Expand方法和前面提到的AsQueryable,我们终于可以得到一个编译和运行都很好的语句:

// build the entire predicate beforehand (PredicateBuilder + AsQueryable):
var complexPredicate = GetComplexPredicate();
var condition = PredicateBuilder.True<Customer>()
    .And(c => c.Country == "US")
    .And(c => c.Invoice.AsQueryable().Any(complexPredicate));

// apply criteria to query (using Expand):
var result = repository.Customer.Where(condition.Expand()).ToList();
于 2013-06-26T17:07:16.070 回答