web-dev-qa-db-ja.com

LINQクエリの再利用

これは結果の再利用ではなく、ステートメント自体に関するものです。また、次のようにvarを使用する場合のエラーについても説明しません。 LINQ to SQL:ラムダ式を再利用

まったくの好奇心から、単一のLINQステートメントを再利用できるかどうか疑問に思いました。

次のLINQステートメントがあるとしましょう。

_.Where(x => x.Contains(""));
_

ステートメントx => x.Contains("")を抽出し、後で別のクラスで使用するために、これへの何らかの参照を使用することは可能ですか?

だから私はそれを次のように呼ぶことができます:.Where(previouslySavedStatement);

35
Blaatz0r

変数に格納できます。 IQueryableを使用している場合は、次を使用します。

System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");

IEnumerableを使用している場合は、次を使用します。

Func<Foo, bool> selector = x => x.Contains("");

そしてそれをクエリで使用します:

query.Where(selector);
41
Hamid Pourjam

はい、再利用するクエリを含む関数を記述できます。この関数は、IQueryable <T>を取得して返します。

   public IQueryable<T> ContainsEmpty(IQueryable<T> query)
   {
       return query.Where(x => x.Contains(""));
   }

今、あなたはそれを再利用することができます:

   query1 = ContainsEmpty(query1);
   query2 = ContainsEmpty(another);
8
user1023602

場合によります。 Whereメソッドには、Enumerable.WhereQueryable.Whereの2つがあります。 .WhereIEnumerableに適用する場合は、最初のものが呼び出されますが、IQueryableに適用する場合は、2番目のものが呼び出されます。

Enumerable.WhereFuncを取り込むため、再利用できません。 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);
6
Shlomo

私はこの懸念に正確に対処するためにライブラリを作成しました。これは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)));

他にもいくつかの機能がありますが、本当に役立つと思いますので、チェックしてください:)

1
crazy_crank