4

Определенный набор критериев, которые встречаются во многих разных запросах в нашем приложении, постепенно усложняется. Для того, чтобы избежать дублирования этого кода, я хочу, чтобы разделить эти критерии из в метод, который возвращает условия как Expression, что в свою очередь может быть применен в случае необходимости:Многоразовые предикатные выражения в запросах LINQ to Entities

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

Есть две части к этому вопросу:

Как использовать предикатные выражения на свойства навигации внутри запроса L2E?

L2E позволяет использовать метод расширения AsQueryable в запросе. Это означает, что я могу преобразовать ICollection в IQueryable и применить выражение предиката. Все идет нормально. Однако он может скомпилироваться, но он все равно не будет работать, поскольку L2E не будет знать, что делать с предопределенным выражением из метода GetComplexPredicate. Это приводит нас к:

Как объединить несколько отдельных предикатных выражений в один?

чрезвычайно полезны LINQKit можно легко объединить несколько предиката в одно выражение с использованием PredicateBuilder. С Развернуть метод из LINQKit и вышеупомянутый 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();