因此... EF6正在創建一個可怕的低效查詢。我有一個查詢針對具有三種不同類型地址的數據源。我有一個地址標識列表,這些地址標識可能是用戶試圖使用的新標識的重複項。理想情況下,我希望此查詢檢查是否有多個地址標識符都位於給定ID集合中。目前此查詢:如何讓EF6在(...)查詢中生成高效
return await _tickets.Where(t =>
t.Metadata is SIFTEscalationMetadata && (
addesses.Any(a => a == (t.Metadata as SIFTEscalationMetadata).Address.Id) ||
addesses.Any(a => a == (t.Metadata as SIFTEscalationMetadata).AddressEntered.Id) ||
addesses.Any(a => a == (t.Metadata as SIFTEscalationMetadata).CleanedAddress.Id))).ToArrayAsync();
正在成爲這樣的:
SELECT
[Project1].[TicketId] AS [TicketId],
[Project1].[TicketType] AS [TicketType],
[Project1].[Opened] AS [Opened],
[Project1].[Closed] AS [Closed],
[Project1].[Modified] AS [Modified],
[Project1].[EscalationStatusText] AS [EscalationStatusText],
[Project1].[QualificationStatusText] AS [QualificationStatusText],
[Project1].[ProductsText] AS [ProductsText],
[Project1].[Cancelled] AS [Cancelled],
[Project1].[CancellationReason_Id] AS [CancellationReason_Id],
[Project1].[CreatedBy_Id] AS [CreatedBy_Id],
[Project1].[Metadata_Id] AS [Metadata_Id],
[Project1].[NotesContainer_Id] AS [NotesContainer_Id]
FROM (SELECT
[Extent1].[TicketId] AS [TicketId],
[Extent1].[TicketType] AS [TicketType],
[Extent1].[Opened] AS [Opened],
[Extent1].[Closed] AS [Closed],
[Extent1].[Modified] AS [Modified],
[Extent1].[EscalationStatusText] AS [EscalationStatusText],
[Extent1].[QualificationStatusText] AS [QualificationStatusText],
[Extent1].[ProductsText] AS [ProductsText],
[Extent1].[Cancelled] AS [Cancelled],
[Extent1].[CancellationReason_Id] AS [CancellationReason_Id],
[Extent1].[CreatedBy_Id] AS [CreatedBy_Id],
[Extent1].[Metadata_Id] AS [Metadata_Id],
[Extent1].[NotesContainer_Id] AS [NotesContainer_Id],
CASE WHEN ([Extent2].[TicketMetadataID] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE '2X0X' END AS [C1]
FROM [dbo].[Tickets] AS [Extent1]
LEFT OUTER JOIN [dbo].[TicketMetadata] AS [Extent2] ON ([Extent2].[Discriminator] = N'SIFTEscalationMetadata') AND ([Extent1].[Metadata_Id] = [Extent2].[TicketMetadataID])
) AS [Project1]
WHERE ([Project1].[C1] LIKE '2X0X%') AND ((EXISTS (SELECT
1 AS [C1]
FROM (SELECT
486524 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable1]
UNION ALL
SELECT
486525 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable2]
UNION ALL
SELECT
486526 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable3]
UNION ALL
SELECT
508376 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable4]
UNION ALL
SELECT
508377 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable5]
UNION ALL
SELECT
508378 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable6]) AS [UnionAll5]
LEFT OUTER JOIN (SELECT
[Extent3].[Address_Id] AS [Address_Id],
'2X0X' AS [C1]
FROM [dbo].[TicketMetadata] AS [Extent3]
WHERE ([Extent3].[Discriminator] = N'SIFTEscalationMetadata') AND ([Project1].[Metadata_Id] = [Extent3].[TicketMetadataID])) AS [Project8] ON 1 = 1
WHERE [UnionAll5].[C1] = (CASE WHEN ([Project8].[C1] LIKE '2X0X%') THEN [Project8].[Address_Id] END)
)) OR (EXISTS (SELECT
1 AS [C1]
FROM (SELECT
486524 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable7]
UNION ALL
SELECT
486525 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable8]
UNION ALL
SELECT
486526 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable9]
UNION ALL
SELECT
508376 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable10]
UNION ALL
SELECT
508377 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable11]
UNION ALL
SELECT
508378 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable12]) AS [UnionAll10]
LEFT OUTER JOIN (SELECT
[Extent4].[AddressEntered_Id] AS [AddressEntered_Id],
'2X0X' AS [C1]
FROM [dbo].[TicketMetadata] AS [Extent4]
WHERE ([Extent4].[Discriminator] = N'SIFTEscalationMetadata') AND ([Project1].[Metadata_Id] = [Extent4].[TicketMetadataID])) AS [Project16] ON 1 = 1
WHERE [UnionAll10].[C1] = (CASE WHEN ([Project16].[C1] LIKE '2X0X%') THEN [Project16].[AddressEntered_Id] END)
)) OR (EXISTS (SELECT
1 AS [C1]
FROM (SELECT
486524 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable13]
UNION ALL
SELECT
486525 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable14]
UNION ALL
SELECT
486526 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable15]
UNION ALL
SELECT
508376 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable16]
UNION ALL
SELECT
508377 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable17]
UNION ALL
SELECT
508378 AS [C1]
FROM (SELECT 1 AS X) AS [SingleRowTable18]) AS [UnionAll15]
LEFT OUTER JOIN (SELECT
[Extent5].[CleanedAddress_Id] AS [CleanedAddress_Id],
'2X0X' AS [C1]
FROM [dbo].[TicketMetadata] AS [Extent5]
WHERE ([Extent5].[Discriminator] = N'SIFTEscalationMetadata') AND ([Project1].[Metadata_Id] = [Extent5].[TicketMetadataID])) AS [Project24] ON 1 = 1
WHERE [UnionAll15].[C1] = (CASE WHEN ([Project24].[C1] LIKE '2X0X%') THEN [Project24].[CleanedAddress_Id] END)
)))
什麼是讓EF在這裏產生更好的查詢的最佳方式?這將是很好,如果它可能只是做:
SELECT ...
WHERE Address_Id in(486524, 486525, 486526, 508376, 508377, 508378)
OR AddressEntered_Id in(486524, 486525, 486526, 508376, 508377, 508378)
OR CleanedAddress_Id in(486524, 486525, 486526, 508376, 508377, 508378)
'包含()'產生更好的SQL嗎?包含((t.Metadata as SIFTEscalationMetadata).Address.Id)|| ......對於小數據集,我已經看到EF5在使用Contains時會生成一個簡短的IN()。 –
謝謝,就是這樣。 – Jereme