Допустим, у вас есть:
Expression<Func<Person, bool>> isAdult = p1 => p1.Age >= 18;
// I've given the parameter a different name to allow you to differentiate.
Expression<Func<Person, bool>> isMale = p2 => p2.Gender == "Male";
А затем объедините их с PredicateBuilder
var isAdultMale = isAdult.And(isMale);
Результатом PredicateBuilder
является выражение, которое выглядит следующим образом:
// Invoke has no direct equivalent in C# lambda expressions.
p1 => p1.Age >= 18 && Invoke(p2 => p2.Gender == "Male", p1)
Как вы видете:
- Полученная лямбда повторно использует параметры первого выражения.
- Имеет тело, которое вызывает второе выражение, передавая параметры первого выражения в качестве замены параметров второго выражения. Полученный результат
InvocationExpression
похож на выражение-эквивалент вызова метода (вызов подпрограммы путем передачи аргументов для параметров).
And
s тело первого выражения и это InvocationExpression
вместе, чтобы создать тело результирующей лямбды.
Идея состоит в том, что провайдер LINQ должен понимать семантику этой операции и предпринимать разумные действия (например, генерировать SQL, подобный WHERE age >= 18 AND gender = 'Male'
).
Однако часто у провайдеров возникают проблемы с InvocationExpression
s из-за очевидных сложностей обработки «вложенного вызова выражения внутри выражения».
Чтобы обойти это, LINQKit также предоставляет помощник Expand
. По сути, это «встраивает» вызов вызова, заменяя вызов телом вложенного выражения, соответствующим образом заменяя использование параметров вложенного выражения (в данном случае, заменяя p2
на p1
). Это должно произвести что-то вроде:
p1 => p1.Age >= 18 && p1.Gender == "Male"
Обратите внимание, что именно так вы бы вручную объединили эти предикаты, если бы сделали это самостоятельно в лямбда-выражении. Но с помощью LINQKit вы можете получить эти предикаты из независимых источников и легко их комбинировать:
- Без написания кода выражения "от руки".
- Необязательно, таким образом, чтобы потребители результирующей лямбды были прозрачными.
person
Ani
schedule
15.07.2012
PredicateBuilder
— это не C# in Depth, а C# в двух словах - person Jon Skeet   schedule 15.07.2012