我已經解決了我的問題,但是因爲我已經嘗試過並且未能解決它,而且這一次花了我很多努力,我想發佈問題,如果沒有人有更好的答案,我的解決方案,所以我不會忘記未來如何做到這一點,並幫助任何其他人面臨類似的挑戰。我的挑戰是這樣的:如何最佳地合併LINQ-to-SQL查詢
我有用於過濾的選項列表的功能,只返回那些大量的跟蹤,並在適用時,也只能說明項目指定模式相匹配:
Private Shared Function FilterResultsLot(ByVal source As IQueryable(Of Item), _
ByVal itemCode As String) As IQueryable(Of Item)
If HasFilter(itemCode, True) Then
Return From row In source Where row.ItemDetail.IsLotTraced AndAlso _
row.ItemCode.ToLower() Like itemCode.ToLower()
Else
Return From row In source Where row.ItemDetail.IsLotTraced
End If
End Function
另一個要求過來了,我希望能夠概括出很多追溯標準爲一般的過濾器,所以我創造了這個功能:
Private Shared Function FilterResults(source As IQueryable(Of Item), _
itemCode As String, filter As Func(Of Item, Boolean)) As IQueryable(Of Item)
Dim predicate As Func(Of Item, Boolean)
If HasFilter(itemCode, True) Then
predicate = Function(row) row.ItemCode.ToLower() Like itemCode.ToLower() AndAlso filter.Invoke(row)
Else
predicate = filter
End If
Return source.Where(predicate).AsQueryable()
End Function
而且該功能通過LINQ到SQL的作品,但它失去了顯著優化。而第一個函數將執行SQL查詢結尾:
FROM [dbo].[OITM] AS [t0]
LEFT OUTER JOIN [dbo].[FSE_ItemDetail] AS [t1] ON [t1].[ItemCode] = [t0].[ItemCode]
WHERE ([t1].[IsLotTraced] = 1) AND (LOWER([t0].[ItemCode]) LIKE @p0 ESCAPE ''~'')
第二個將執行與這些神經末梢多個SQL查詢(可能還有更多):
FROM [dbo].[OITM] AS [t0]
FROM [dbo].[FSE_ItemDetail] AS [t0]
WHERE [t0].[ItemCode] = @p0',N'@p0 nvarchar(4000)',@p0=N'BF-BIKE'
FROM [dbo].[FSE_ItemDetail] AS [t0]
WHERE [t0].[ItemCode] = @p0',N'@p0 nvarchar(4000)',@p0=N'BF-BIKE-ITEM'
所以,問題是如何結合LINQ-to-SQL將表達式委託給一個表達式,而不調用Invoke或AsQueryable,或者不會失去最佳執行。
如果這是C#,我會嘗試替換所有使用'Func <>' 'Expression>',因爲編譯器可以將lambda翻譯成任意一個。這也是VB的真實嗎?你可以給一個'Expression(Of Func(Of whatever))'賦值一個內聯函數表達式嗎? –
AakashM
2012-03-13 18:50:39
是的,我想我嘗試過,但仍不知道如何調用表達式。您會注意到我提出的解決方案完全符合您的建議,但也找到了「調用」表達式(將它合併到Queryable的表達式樹中)的方法,這是我缺少的部分。 – BlueMonkMN 2012-03-13 19:15:54