2016-12-07 10 views
3

私はLinqの初心者であり、表現木を持つ初心者です。 Dynamic Linq where節がOutOfMemoryExceptionをスローする

public Func<TSource,bool> SimpleFilter<TSource> (string property, object value) 
{ 
    var type = typeof(TSource); 
    var pe = Expression.Parameter(type, "p"); 
    var propertyReference = Expression.Property(pe,property); 
    var constantReference = Expression.Constant(value); 
    var ret = Expression.Lambda<Func<TSource, bool>> 
     (Expression.Equal(propertyReference, constantReference), new[] { pe }); 
    return ret.Compile(); 
} 

私は関数を呼び出す
https://www.simple-talk.com/dotnet/net-framework/dynamic-linq-queries-with-expression-trees/

(p => p.JobCustomerId == 449152)それ 利回り SimpleFilter("JobCustomerID", 449152)として正しいである:

は、私は私が見つけ句はどこシンプルなLINQのを構築する一般的な表現ルーチンを持っています。

Linqステートメントにその基準を手動で配置すると、正しい結果が得られます。

var jj = db.VW_Job_List.Where((p => p.JobCustomerId == 449152)); 

ただし、フィルタ関数によって呼び出されたとき、LinqはOutOfMemoryExceptionをスローします。 それは次のように自分のアプリケーションに呼び出されます。私は、テキストの基準で関数を呼び出す場合は、それが適切に返し

var jj = db.VW_Job_List.Where(SimpleFilter<VW_Job_List>("JobCustomerID", 449152)); 

var jj = db.VW_Job_List.Where(SimpleFilter<VW_Job_List>("CompanyCode", "LCS")); 

があることが必要である整数の変数の使用についての具体的な何かがあります収容?間違ったコードがありますか?どんな考えや洞察も認められるでしょう。

+0

を?はいの場合、VW_Job_Listテーブルには何行ありますか? – Evk

答えて

3

2つのコール

var jj = db.VW_Job_List.Where((p => p.JobCustomerId == 449152)); 

var jj = db.VW_Job_List.Where(SimpleFilter<VW_Job_List>("JobCustomerID", 449152)); 

は等価ではありません。最初はQueryable.Whereに解決されます。したがって、フィルタはデータベース内に適用され、2番目のフィルタはEnumerable.Whereになります。このため、テーブル全体がメモリにロードされ、そこでフィルタが適用されます。

問題はSimpleFilterのがFunc<TSource, bool>の返品タイプです。等価にするには、Expression<Func<TSource, bool>>にする必要があります。視覚的には同じように見えますが、IQueryable<T>に適用すると、異なるオーバーロード解像度のためにラムダ式とラムダデリゲートには大きな違いがあります。

ので、このような方法を変更して、もう一度試してください:あなたはデータベースを照会

public Expression<Func<TSource,bool>> SimpleFilter<TSource> (string property, object value) 
{ 
    var type = typeof(TSource); 
    var pe = Expression.Parameter(type, "p"); 
    var propertyReference = Expression.Property(pe,property); 
    var constantReference = Expression.Constant(value); 
    var ret = Expression.Lambda<Func<TSource, bool>> 
     (Expression.Equal(propertyReference, constantReference), new[] { pe }); 
    return ret; // No .Compile() 
} 
+0

Hummm興味深い。私は 'Expression <...>'とEF –

+0

と一緒に使用しないことの違いについて決して解読したことはありません。これにより、Webアプリケーションのパフォーマンスが低下することがあります。ありがとうございました。 –