我有一個SQL Server 2008上有150萬條記錄的表。有一個索引爲varchar的列「ReferenzNummer」。實體框架:交叉連接導致OutOfMemoryException
在SQL Management Studio中執行下面的查詢工作,是快:
SELECT v1.Id, v2.Id FROM Vorpapier as v1 cross join Vorpapier as v2
WHERE v1.ReferenzNummer LIKE '7bd48e26-58d9-4c31-a755-a15500bce4c4'
AND v2.ReferenzNummer LIKE '7bd4%'
(我知道查詢沒有太大的意義就是這樣,會有更多的限制,但這不是重要的是,片刻)
現在我想從實體框架5.0執行這樣的查詢,我的LINQ看起來是這樣的:
var result = (from v1 in vorpapierRepository.DbSet
from v2 in vorpapierRepository.DbSet
where v1.ReferenzNummer == "7bd48e26-58d9-4c31-a755-a15500bce4c4" &&
v2.ReferenzNummer.StartsWith("7bd4")
select new { V1 = v1.Id, V2 = v2.Id })
.Take(10)
.ToList();
這種嘗試加載整個表INT內存,一段時間後導致OutOfMemoryException。我試圖移動WHERE部分,但沒有成功:
var result = (from v1 in vorpapierRepository.DbSet.Where(v => v.ReferenzNummer == "7bd48e26-58d9-4c31-a755-a15500bce4c4")
from v2 in vorpapierRepository.DbSet.Where(v => v.ReferenzNummer.StartsWith("7bd4"))
select new { V1 = v1.Id, V2 = v2.Id })
.Take(10)
.ToList();
是否可以告訴實體框架來創建一個交叉連接語句,像我自己寫的嗎?
更新1
的EF生成的SQL看起來是這樣的(用於查詢)
SELECT [Extent1].[Id] AS [Id],
[Extent1].[VorpapierArtId] AS [VorpapierArtId],
[Extent1].[ReferenzNummer] AS [ReferenzNummer],
[Extent1].[IsImported] AS [IsImported],
[Extent1].[DwhVorpapierId] AS [DwhVorpapierId],
[Extent1].[Datenbasis_Id] AS [Datenbasis_Id]
FROM [dbo].[Vorpapier] AS [Extent1]
更新2
當我改變了LINQ查詢和參加表本身在字段DatenbasisIDd(這不完全是我想要的,但它可能工作),EF創建一個連接:
var result = (from v1 in vorpapierRepository.DbSet
join v2 in vorpapierRepository.DbSet
on v1.DatenbasisId equals v2.DatenbasisId
where v1.ReferenzNummer == "7bd48e26-58d9-4c31-a755-a15500bce4c4" && v2.ReferenzNummer.StartsWith("7bd4")
select new { V1 = v1.Id, V2 = v2.Id })
.Take(10)
.ToList();
生成的SQL查詢如下所示。它的工作原理並且足夠快。
SELECT TOP (10) 1 AS [C1],
[Extent1].[Id] AS [Id],
[Extent2].[Id] AS [Id1]
FROM [dbo].[Vorpapier] AS [Extent1]
INNER JOIN [dbo].[Vorpapier] AS [Extent2]
ON ([Extent1].[Datenbasis_Id] = [Extent2].[Datenbasis_Id])
OR (([Extent1].[Datenbasis_Id] IS NULL)
AND ([Extent2].[Datenbasis_Id] IS NULL))
WHERE (N'7bd48e26-58d9-4c31-a755-a15500bce4c4' = [Extent1].[ReferenzNummer])
AND ([Extent2].[ReferenzNummer] LIKE N'7bd4%')
我仍然沒有看到,爲什麼EF不會在原始查詢中創建交叉連接。它只是不被支持?
您必須顯示「VorpapierRepository」實現。我假設存儲庫實現的問題,因爲你LINQ看起來像是正確的。 –
@ hamlet-hakobyan:'vorpapierRepository'返回EF DbSet。因此,該存儲庫的實施應該不重要。 – delixfe
@delixfe你只能假設。 –