1

We have a simple LOB application that:

  • pulls data from EF
  • serves data across the wire with WCF Data Services
  • そのデータを Telerik のRadGridViewにレンダリングします

これは、ユーザーが必要なすべてのオプションを提示する組み込みの Telerik フィルター コントロールを使用してデータをフィルター処理できるため、既定のシナリオでは非常にうまく機能します。

この問題は、'Contains' 演算子が使用されている場合に WCF Data Services から送信されたクエリを再構築するときに発生します。

  • WCF Data Services は、一連の "IIF" ラムダ式を追加します。
  • 次に、EF は T-SQL CASE ステートメントに展開されます

これは、次のようなクエリを取ります。

SELECT TOP (25) 
[Project1].[TaskID] AS [TaskID], 
[Project1].[ProductSubmissionID] AS [ProductSubmissionID], 
...
FROM ( SELECT 
    [Extent1].[TaskID] AS [TaskID], 
    [Extent1].[ProductSubmissionID] AS [ProductSubmissionID], 
    ...
FROM     [dbo].[Task] AS [Extent1]
    LEFT OUTER JOIN [dbo].[OperationDataProduct] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID]
    LEFT OUTER JOIN [dbo].[vProductOwnership] AS [Extent3] ON [Extent1].[ProductID] = [Extent3].[ProductID]
    LEFT OUTER JOIN [dbo].[User] AS [Extent4] ON [Extent2].[ChannelManagerID] = [Extent4].[UserID]
    LEFT OUTER JOIN [dbo].[User] AS [Extent5] ON [Extent2].[ProductOwnerID] = [Extent5].[UserID]
    WHERE [Extent1].Type IN ('Content','Concept','Financial') AND [Extent1].MarketplaceName LIKE '%prod%'

次のようになります。

SELECT TOP (25) 
[Project1].[TaskID] AS [TaskID], 
[Project1].[ProductSubmissionID] AS [ProductSubmissionID], 
...
FROM ( SELECT 
    [Extent1].[TaskID] AS [TaskID], 
    [Extent1].[ProductSubmissionID] AS [ProductSubmissionID], 
    ...
FROM     [dbo].[Task] AS [Extent1]
    LEFT OUTER JOIN [dbo].[OperationDataProduct] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID]
    LEFT OUTER JOIN [dbo].[vProductOwnership] AS [Extent3] ON [Extent1].[ProductID] = [Extent3].[ProductID]
    LEFT OUTER JOIN [dbo].[User] AS [Extent4] ON [Extent2].[ChannelManagerID] = [Extent4].[UserID]
    LEFT OUTER JOIN [dbo].[User] AS [Extent5] ON [Extent2].[ProductOwnerID] = [Extent5].[UserID]
    WHERE (CASE WHEN (CASE WHEN (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial'))) THEN cast(1 as bit) WHEN ( NOT (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial')))) THEN cast(0 as bit) END IS NULL) THEN cast(0 as bit) WHEN (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial'))) THEN cast(1 as bit) WHEN ( NOT (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial')))) THEN cast(0 as bit) END) = 1
)  AS [Project1]
ORDER BY [Project1].[TaskID] ASC

私の質問は次のとおりです。以前にこの問題に遭遇した人はいますか?低コストの解決策はありますか?

解決策として EF QueryProvider を書き直すことはできますが、必ずしも低コストではありません。

ティア

4

1 に答える 1

2

この問題を修正するために QueryProvider を作成しました。最終的には当初の予想よりも低コストになりましたが、それでも静かで不要な複雑さが少し追加されています。IQToolkit には、これを開始する方法の適切な例がいくつかあります。

于 2011-12-16T22:26:26.573 に答える