これは結果の再利用ではなく、ステートメント自体に関するものです。また、次のようにvarを使用する場合のエラーについても説明しません。 LINQ to SQL:ラムダ式を再利用
まったくの好奇心から、単一のLINQステートメントを再利用できるかどうか疑問に思いました。
次のLINQステートメントがあるとしましょう。
_.Where(x => x.Contains(""));
_
ステートメントx => x.Contains("")
を抽出し、後で別のクラスで使用するために、これへの何らかの参照を使用することは可能ですか?
だから私はそれを次のように呼ぶことができます:.Where(previouslySavedStatement);
変数に格納できます。 IQueryable
を使用している場合は、次を使用します。
System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");
IEnumerable
を使用している場合は、次を使用します。
Func<Foo, bool> selector = x => x.Contains("");
そしてそれをクエリで使用します:
query.Where(selector);
はい、再利用するクエリを含む関数を記述できます。この関数は、IQueryable <T>を取得して返します。
public IQueryable<T> ContainsEmpty(IQueryable<T> query)
{
return query.Where(x => x.Contains(""));
}
今、あなたはそれを再利用することができます:
query1 = ContainsEmpty(query1);
query2 = ContainsEmpty(another);
場合によります。 Where
メソッドには、Enumerable.Where
とQueryable.Where
の2つがあります。 .Where
をIEnumerable
に適用する場合は、最初のものが呼び出されますが、IQueryable
に適用する場合は、2番目のものが呼び出されます。
Enumerable.Where
はFunc
を取り込むため、再利用できません。 Queryable.Where
は式を取り込むため、再利用できます。あなたは次のようにそうすることができます:
var x = new List<string>().AsQueryable();
var query = x.Where (n => n.Contains("some string"));
//Extract the lambda clause
var expr = query.Expression;
var methodExpr = (MethodCallExpression)expr;
var quoteExpr = (UnaryExpression)methodExpr.Arguments[1];
var funcExpr = (Expression<Func<string, bool>>)quoteExpr.Operand;
その後、where式を再適用できます。
var query2 = x.Where(funcExpr);
私はこの懸念に正確に対処するためにライブラリを作成しました。これはCLinkと呼ばれ、EntityFrameworkの実装は次の場所にあります。 https://www.nuget.org/packages/CLinq.EntityFramework
クエリスニペットを作成し、linqクエリのどこでも使用できます。 Hamidの例に従って、次の式を作成します。
System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");
これで、次のようにlinqクエリのどこでもこのクエリを使用できます。
query.AsComposable().Where(o => selector.Pass(o));
この簡単な例に加えて、クエリスニペットを組み合わせることができます。
query.AsComposable().Where(o => selector.Pass(o) || anotherSelector.Pass(o));
またはそれらを一緒にマージすることさえできます:
query.AsComposable().Where(o => anotherSelector.Pass(selector.Pass(o)));
他にもいくつかの機能がありますが、本当に役立つと思いますので、チェックしてください:)