在LINQ to Entities查询中重复使用谓词表达式

7
我们应用程序中的多个不同查询都包含了一组特定的条件。为避免代码重复,我想将这些条件拆分为一个方法,并返回一个表达式,以便随时应用到需要的地方。
public Expression<Func<Invoice, bool>> GetComplexPredicate()
{
    // complex predicate is returned as an Expression:
    return c => ...
}

直接重用:

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

然而,下面的语句无法编译,因为只是一个。
var result = repository.Customer
    .Where(c => c.Country == "US" && c.Invoice.Any(GetComplexPredicate()))

有没有可能像这样使用表达式?
1个回答

9

这个问题有两个部分:

如何在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();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接