我正在爲一系列數據庫結果集編寫包裝器對象。在這樣做時,我在使用LINQ和Lambda表達式查詢時發現了一個問題。具體來說,在lambda中調用方法似乎總是使結果集爲空,並且實際上並不會激發我試圖過濾的方法。下面的代碼:VB.NET Lambda不會調用方法
' Query and filter container results
Public Function [Filter](pFilter As IFilter(Of T)) As System.Linq.IQueryable(Of T)
' THIS YIELDS AN EMPTY SET EVEN WHEN pFilter.Test(o) ALWAYS RETURNS TRUE
Dim lResult As System.Linq.IQueryable(Of T) = mTable.Where(Function(o As T) pFilter.Test(o))
Return lResult
End Function
pFilter實現IFilter的與此簽名:
Public Interface IFilter(Of T)
Function Test(ByVal pObject As T) As Boolean
End Interface
我已經休息指出pFilter.Test(o)
,發現它實際上從來不叫。奇怪的是,如果我將pFilter.Test(o)
替換爲True,我會按預期收到整個記錄表。而且,在任何情況下,我都不會收到編譯時或運行時錯誤。
我是很新,lambda表達式和LINQ所以充分認識到我可能不明白我試圖完成的極限。任何幫助是極大的讚賞!
SOLUTION: 我已經標記了一個解決方案,因爲作者讓我走上了正軌。這個問題的真正本質源於我試圖強制.NET函數變成LINQ可能變成SQL語句的東西(這是不可能的)。爲了解決這個問題,我已經改變了我的IFilter,使其返回System.Linq.Expressions.Expression(Of Func(Of T,Boolean))。現在我可以創建強類型的過濾器,它返回謂詞並直接將它們傳遞給Where()而不使用lambda表達式。我也使用LinqKit爲那些可能完成類似任務的人更容易地做這項工作。
你能發表一些我們可以用來重現你的問題的代碼嗎? – Neolisk
你如何觀察空集?你不能在該點放置一個斷點來知道它是否調用該方法,因爲在這一點上你只是建立一個表達式樹。您必須將斷點放在實際讀取結果的地方。在那之前它不會運行任何東西。 –