私は自分の問題を解決しましたが、これまでに解決しようとしていたため、これを解決するのに時間がかかりました。誰もより良い答えを持っていなければ、私の解決策で、私はこれを将来どのように行うのか、誰かが同様の課題に直面するのを忘れることはありません。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'
そこで問題は、どのように組み合わせるかでありますInvokeまたはAsQueryableを呼び出さずに、または最適な実行を失うことなく、LINQ-to-SQLデリゲート式を1つにデリゲートします。
これはC#の場合、コンパイラはラムダをどちらかに変換することができるので、 'Expression 'でコンパイルできます。これはVBにも当てはまりますか?インライン関数式を 'Expression(Of Func(Of whatever))'に割り当てることができますか? –
AakashM
はい、私はそれを試みたと思うが、まだ表現を呼び出す方法を知らなかった。私が思いついた解決策は、あなたが提案したものとまったく同じですが、式を "呼び出す"方法(Queryableの式ツリーにマージする方法)があります。これは欠けていた部分でした。 – BlueMonkMN