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 がクロス結合を作成しない理由はまだわかりません。単にサポートされていないのですか?

4

1 に答える 1

0

linq ステートメントで結合を使用すると、SQL Server に戻されます。linq の結合演算子の例を次に示します: http://code.msdn.microsoft.com/LINQ-Join-Operators-dabef4e9

于 2013-02-04T16:31:22.533 に答える