あなたが持っているとしましょう:
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)
ご覧のように:
- 結果のラムダは、最初の式のパラメーターを再利用します。
- 2番目の式のパラメーターの代わりに最初の式のパラメーターを渡すことによって2番目の式を呼び出す本体があります。結果
InvocationExpression
は、メソッド呼び出し(パラメーターの引数を渡すことによってルーチンを呼び出す)と同等の式のようなものです。
And
■最初の式の本体とこれInvocationExpression
を合わせて、結果のラムダの本体を生成します。
LINQプロバイダーは、この操作のセマンティクスを理解し、適切なアクションを実行できる必要があります(たとえば、のようなSQLを生成するWHERE age >= 18 AND gender = 'Male'
)。
ただし、多くの場合、プロバイダーはInvocationExpression
、「ネストされた式-式内の呼び出し」の処理が明らかに複雑になるため、sに問題があります。
これを回避するために、LINQKitはExpand
ヘルパーも提供します。これは基本的に、呼び出しをネストされた式の本体に置き換え、ネストされた式のパラメーターの使用を適切に置き換えることによって(この場合はに置き換えp2
て) 、呼び出し呼び出しをスマートに「インライン化」しますp1
。これにより、次のようなものが生成されます。
p1 => p1.Age >= 18 && p1.Gender == "Male"
ラムダで自分で行った場合、これらの述語を手動で組み合わせる方法に注意してください。しかし、LINQKitを使用すると、これらの述語を独立したソースから取得して、簡単に組み合わせることができます。
- 「手作業」の式コードを記述せずに。
- オプションで、結果のラムダのコンシューマーに対して透過的な方法で。