2013-02-04 32 views
3

我有一個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不會在原始查詢中創建交叉連接。它只是不被支持?

+0

您必須顯示「VorpapierRepository」實現。我假設存儲庫實現的問題,因爲你LINQ看起來像是正確的。 –

+0

@ hamlet-hakobyan:'vorpapierRepository'返回EF DbSet。因此,該存儲庫的實施應該不重要。 – delixfe

+0

@delixfe你只能假設。 –

回答