2015-12-17 11 views
29

これは結果の再利用ではなく、文そのものの詳細です。 上記のようにvarを使用してもエラーではありません:LINQ to SQL: Reuse lambda expressionLINQクエリの再利用

私は単なるLINQ文を再利用できるかどうか疑問に思っていました。

は、私は、次のLINQ文を考えてみましょう:

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

それは、言うことができます、別のクラスを声明x => x.Contains("")を抽出し、中、後の使用のために、このを参照のいくつかの種類を使用することは可能ですか?

だから私は次のようにそれを呼び出すことができます:あなたは変数に格納することができます.Where(previouslySavedStatement);

+5

変数に入れます。 'Func func = x => x.contains(" ");' –

+3

@wudzikこれは重複していません。重複参照とは、結果を再利用することを指します。質問は、クエリ自体の再利用について質問します。 – Shlomo

+0

ありがとうShlomo :)ちょうど自分自身を編集しました – Blaatz0r

答えて

35

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

あなたがIEnumerableを使用している場合は、使用します:

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

をそして、あなたのクエリでそれを使用する:あなたはIQueryableで作業している場合は、使用

query.Where(selector); 
+6

あなたは '...代わりに'のIQueryable 'あなただけ='のFunc セレクタを使用するの 'IEnumerableを'で作業している場合は、しかし、あなたはのIQueryable 'あなたが最も挑戦的にしたい'使用している場合、 'Expression >'バージョンを使用してください。 –

+1

@ScottChamberlainほとんどの私のステートメントはIEnumerable ですので、 – Blaatz0r

+1

@ Blaatz0rの頭に感謝します。式のバージョンがある場合は、 'Func selector2 = selector.Compile();'を実行して代理人に変換することもできますデリゲートからエクスプレッションに向かうことはできません。 –

5

それは依存しています。 2つの方法、Enumerable.WhereおよびQueryable.Whereがあります。 .Whereを最初のものよりもIEnumerableに適用する場合は、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; 

をあなたは、後で再適用どこ表現することができます::次のようにこれを行うことができます

var query2 = x.Where(funcExpr); 
+1

あなたは受け入れられた答えを読んだことがありますか? – CSharpie

+2

はい、私も受け入れられた答えを読んで、私はあまりにも質問を読む。たとえ受け入れられた答えよりもよく尋ねられたとしても、私の答えは質問に答えると私は信じています。 – Shlomo

8

はい、あなたが取る再利用するクエリを含む関数を記述することができますし、 IQueryable < Tを返す今>

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

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

query1 = ContainsEmpty(query1); 
    query2 = ContainsEmpty(another); 
+0

+1これはOPの質問に直接答えるものではありませんが、問題を解決するにはもっと良い方法です(ただし、なぜIEnumerable の代わりに 'IQueryable 'を選んだのですか?)_ –

+1

データ型がで指定されていません質問には、 "LINQ to SQL"とタイトルに "query"があるので、IQueryable :-)を推測しました – buffjape