Reusable predicate expressions in LINQ to Entities queries

孤街浪徒 提交于 2019-11-27 22:25:42

问题


A certain set of criteria that occurs in many different queries throughout our application has slowly grown more complex. To avoid duplication of this code, I want to split these criteria out into a method that returns the conditions as an Expression that can in turn be applied where necessary:

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

Reused as such:

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

However, the statement below won't compile, since c.Invoice is just an ICollection.

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

Is it in any way possible to use the expression like this?


回答1:


There are two parts to this question:

How do I use predicate expressions on navigation properties inside a L2E query?

L2E allows the use of the AsQueryable extension method within a query. This means that I'm able to convert the ICollection to an IQueryable and apply the predicate expression. So far so good. However, it might compile, but it still won't run, since L2E won't know what to do with the predefined expression from the GetComplexPredicate method. This leads us to:

How do I combine several separate predicate expressions into one?

The enormously useful LINQKit can easily combine several predicates into one expression using PredicateBuilder. With the Expand method from LINQKit and the aforementioned AsQueryable, we can finally arrive at a statement that will both compile and run beautifully:

// 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();


来源:https://stackoverflow.com/questions/17326321/reusable-predicate-expressions-in-linq-to-entities-queries

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!