2016-12-07 102 views
3

我是Linq的新手,也是表達式樹的初學者。動態Linq where子句拋出OutOfMemoryException

我有建立一個簡單的LINQ where子句,我發現在一個通用表達式例程:
https://www.simple-talk.com/dotnet/net-framework/dynamic-linq-queries-with-expression-trees/

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(); 
} 

當我調用該函數作爲SimpleFilter("JobCustomerID", 449152)它 收率(p => p.JobCustomerId == 449152)這是正確的。

如果我手動將該條件放在我的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

兩個呼叫

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,因此該過濾器應用於數據庫內部,而第二個 - Enumerable.Where,因此導致將整個表加載到內存中並在其中應用過濾器。

問題是您的SimpleFilter返回類型Func<TSource, bool>。爲了使它們等價,它應該是Expression<Func<TSource, bool>>。請注意,雖然它們在外觀上看起來相同,但由於應用於IQueryable<T>時的過載分辨率不同,因此lambda表達式和lambda代表之間存在巨大差異。

所以,改變方法,這樣,然後再試一次:

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應用程序的性能下降。謝謝。 –