2013-10-07 37 views
2

我有1個LINQ使用這麼多。我試圖創造出返回此LINQ類似方法:經常使用的LINQ返回方法

public static System.Linq.Expressions.Expression<Func<MyEntity, bool>> GetFilteredEntity() { 
     return x => true/*Some condition*/; 
    } 

    public static Func<MyEntity, bool> GetFilteredEntity() { 
     return x => true/*Some condition*/; 
    } 

,並使用該像

db.MyEntities.Where(GetFilteredEntity()); 

是全成,但!我需要使用它像

db.ParentEntities.Where(entity => entity.MyEntities.Where(GetFilteredEntity())); 

此代碼編譯過,但每次當我使用它,我得到了錯誤:

System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first. 

,甚至:

db.ParentEntities.Where(entity => entity.MyEntities.Where(GetFilteredEntity())).ToList(); 

拋出此異常太。

但是,

db.ParentEntities.Where(entity => entity.MyEntities.Where(x => true/*Some condition*/)) 

仍然能正常工作!那麼爲什麼它會發生,並且有辦法繞過這個?

最後的工作代碼

public static Expression<Func<MyEntity, bool>> GetFilteredEntity() { return x => true/*Some condition*/; }

var expression = GetFilteredEntity();

db.ParentEntities.Where(entity => entity.MyEntities.AsQueryable().Where(expression));

而且.AsQueryable()感謝Passing func as parameter in Linq to Entities and 'Internal .NET Framework Data Provider error 1025' error

+0

無關的問題:這個應該做什麼? 'db.ParentEntities.Where(entity => entity.MyEntities。Where(GetFilteredEntity()));''ParentEntity'是否來自'MyEntity'? – Khan

+0

Nope =)它只是採取'ParentEntity'過濾計數'MyEntity'大於...(也是它的問題和解答) –

回答

4

在你的第一個例子中,函數被調用,並翻譯成表達之前,甚至發送到查詢提供。在接下來的兩個例子中,函數調用被嵌入到發送給查詢提供者的表達式中,並且該查詢提供者不知道如何處理該函數調用,所以它只是拋出異常。在另一個表達式中嵌入實際表達式時,沒有函數調用來混淆查詢提供程序。

至於解決方案,只需將函數調用拉出變量。查詢提供商足夠聰明,可以看到您使用了一個關閉的變量,並將其值提取出來。對於一個函數調用,它只是不確定它是否應該評估它,或者試圖將它翻譯成應該在數據庫結尾完成的事情。試圖做一些這兩個將只是很混亂,很難與查詢提供商和使用它的人一起工作。爲了簡化問題,在發送查詢之前,不會執行帶有表達式的函數調用。至於一個封閉的變量,沒有別的辦法可以處理,所以沒有其他任何混淆的行爲。

var expression = GetFilteredEntity(); 
db.ParentEntities.Where(entity => entity.MyEntities.Where(expression)); 
-1

看起來像LazyLoading可能是罪魁禍首,你有沒有嘗試在參數上彈出ToList()?

db.ParentEntities.Where(entity => entity.MyEntities.Where(GetFilteredEntity()).ToList()); 
+0

'GetFilteredEntity()'是*表達式*而不是'IQueryable'。它沒有'ToList'方法。 – Servy

+0

對不起,支架放在錯誤的地方。 – openshac

+0

這仍然行不通。這不像在查詢生成之前可以生成一次列表;該列表基於在查詢中被過濾的實體,所以它仍然需要被翻譯成查詢,並且它仍然不知道如何做到這一點。它會因OP代碼斷裂的原因而中斷。 – Servy