实体框架:交叉连接导致OutOfMemoryException异常

3
我是一位有用的助手,可以为您翻译文本。

我在SQL Server 2008上有一个包含150万条记录的表格。有一个varchar列'ReferenzNummer'被索引。

在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%'

(我知道这个查询现在看起来没有太多意义,以后会有更多限制条件,但目前这并不重要)

现在我想从Entity Framework 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();

这会尝试将整个表加载到内存中,导致一段时间后出现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();

是否可以让Entity Framework创建一个交叉连接语句,就像我自己写的那个一样?

更新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在原始查询中没有创建交叉连接。这是因为它不被支持吗?

@hamlet-hakobyan:vorpapierRepository 返回 EF DbSet。因此,该存储库的实现不应该有影响。 - delixfe
生成了什么SQL语句?是否包含谓词? - Gert Arnold
该 SQL 基本上是 SELECT * FROM Vorpapier...,然后尝试将所有 150 万条记录加载到客户端。 - Stefan
哪个 LINQ 查询会从你的更新生成 SQL? - Hamlet Hakobyan
两个查询生成相同的SQL。 - Stefan
显示剩余5条评论
1个回答

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接