Telerik RadGridView + WCF Data Services + Entity Framework = Ужасная производительность - PullRequest
1 голос
/ 22 октября 2011

У нас есть простое LOB-приложение, которое:

  • извлекает данные из EF
  • и передает данные по сети с помощью WCF Data Services
  • отображает эти данные на Telerik RadGridView

Это действительно хорошо работает в сценарии по умолчанию, так как пользователи могут фильтровать данные с помощью встроенного Telerikэлемент управления фильтра, который представляет все необходимые параметры.

Проблема возникает при повторном построении запроса, отправленного из служб данных WCF, когда используется оператор «Содержит»:

  • Данные WCFСлужбы добавляют несколько лямбда-выражений «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 для решения, но это не такточно низкая стоимость.

TIA

1 Ответ

2 голосов
/ 17 декабря 2011

Мы решили написать QueryProvider для решения этой проблемы. Это оказалось дешевле, чем первоначально ожидалось, но все же добавляет немного ненужной сложности. В IQToolkit есть несколько достойных примеров того, как начать это.

...