2012-10-25 50 views
1

我正在爲一系列數據庫結果集編寫包裝器對象。在這樣做時,我在使用LINQLambda表達式查詢時發現了一個問題。具體來說,在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爲那些可能完成類似任務的人更容易地做這項工作。

+0

你能發表一些我們可以用來重現你的問題的代碼嗎? – Neolisk

+0

你如何觀察空集?你不能在該點放置一個斷點來知道它是否調用該方法,因爲在這一點上你只是建立一個表達式樹。您必須將斷點放在實際讀取結果的地方。在那之前它不會運行任何東西。 –

回答

1

我想我發現你的問題是 - 理解IQueryable的概念。下面是它在這篇文章中說:Lazy Loading With The LazyList

IQueryable is the cornerstone of Linq To Sql, and has (what I think) is a killer feature: delayed execution. IQueryable essentially creates an Expression for you that you can treat as an enumerable list - and only when you iterate or ask for a value will the query be executed.

所以,你可能永遠不會使用的結果,這就是爲什麼它從來沒有所謂。 .NET框架只爲您構建表達式樹,但沒有做任何處理。也可以參考:IQueryable vs. IEnumerable

+0

好吧,基於你在這裏發佈的內容讓我思考如何測試結果集實際上正在加載。所以我通過它在每個循環中。低看,我想我發現問題的真實性質,因爲我收到一個運行時錯誤: 方法'布爾測試(PbShipping.CUSTOMER)'沒有支持轉換到SQL 真的很臭,但現在我知道這只是因爲某種原因默默地失敗。謝謝你的幫助!我將你標記爲答案,因爲它大部分都是正確的,並幫助我找到罪魁禍首! –