为什么Take()返回的行数多于指定的数量?

时间:2016-10-21 22:34:45

标签: c# entity-framework linq

我正在使用Entity Framework查询数据库。为了限制我使用Take(1000)的结果。问题是EF返回超过1000行,#1000之后的所有实体都不包含正确的数据。

这是表结构:

enter image description here

查询如下:

var resultListTmp = db.TinglysEjendom.Where(x => x.EjdStatus == description)
    .Include(x => x.TinglysEjd_ESR.Select(y => y.ESR))               
    .Include(nameof(TingLysMatrikkel))
    .Take(amount).AsNoTracking().ToList();

问题是#1000之后的所有TinglysEjendom实体都没有任何TinglysMatrikkel关系,但是在数据库中它们确实存在。

删除时:

.Include(x => x.TinglysEjd_ESR.Select(y => y.ESR)) 

从查询中,EF返回正确的行数。

TinglysMatrikkel表中的MatrikkelNummer列可以(除其他外)取值:

æ Ø A

有人认为这可能是一个i18n“国际化和本地化”问题。我不知道这是怎么回事。也许有人可以指出我正确的方向?

提前致谢

LINQ将上述查询转换为:

exec sp_executesql N'SELECT 

[UnionAll1].[EjdId] AS [C1], 

[UnionAll1].[EjdId1] AS [C2], 

[UnionAll1].[EjdType] AS [C3], 

[UnionAll1].[BygningsNr] AS [C4], 

[UnionAll1].[TimeshareNr] AS [C5], 

[UnionAll1].[AnpartsNr] AS [C6], 

[UnionAll1].[EjerLejNr] AS [C7], 

[UnionAll1].[Beskrivelse] AS [C8], 

[UnionAll1].[StreetBuildingIdentifier] AS [C9], 

[UnionAll1].[EjdStatus] AS [C10], 

[UnionAll1].[StatusTimestamp] AS [C11], 

[UnionAll1].[IAbonnement] AS [C12], 

[UnionAll1].[AbonnementOpretAttempts] AS [C13], 

[UnionAll1].[AbonnementsId] AS [C14], 

[UnionAll1].[BestemtFastEjendomsNummer] AS [C15], 

[UnionAll1].[UpdateToken] AS [C16], 

[UnionAll1].[FaellesEjendomIdentifikator] AS [C17], 

[UnionAll1].[C1] AS [C18], 

[UnionAll1].[ESRId] AS [C19], 

[UnionAll1].[ESRId1] AS [C20], 

[UnionAll1].[EjdId2] AS [C21], 

[UnionAll1].[Passiv] AS [C22], 

[UnionAll1].[ESRId2] AS [C23], 

[UnionAll1].[EjdId3] AS [C24], 

[UnionAll1].[ESRId3] AS [C25], 

[UnionAll1].[ESR_Kommune] AS [C26], 

[UnionAll1].[ESR_EjdNummer] AS [C27], 

[UnionAll1].[UdgaaetCognito] AS [C28], 

[UnionAll1].[Status] AS [C29], 

[UnionAll1].[C2] AS [C30], 

[UnionAll1].[C3] AS [C31], 

[UnionAll1].[C4] AS [C32], 

[UnionAll1].[C5] AS [C33]

FROM  (SELECT 

    CASE WHEN ([Join1].[ESRId1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1], 

    [Limit1].[EjdId] AS [EjdId], 

    [Limit1].[EjdId] AS [EjdId1], 

    [Limit1].[EjdType] AS [EjdType], 

    [Limit1].[BygningsNr] AS [BygningsNr], 

    [Limit1].[TimeshareNr] AS [TimeshareNr], 

    [Limit1].[AnpartsNr] AS [AnpartsNr], 

    [Limit1].[EjerLejNr] AS [EjerLejNr], 

    [Limit1].[Beskrivelse] AS [Beskrivelse], 

    [Limit1].[StreetBuildingIdentifier] AS [StreetBuildingIdentifier], 

    [Limit1].[EjdStatus] AS [EjdStatus], 

    [Limit1].[StatusTimestamp] AS [StatusTimestamp], 

    [Limit1].[IAbonnement] AS [IAbonnement], 

    [Limit1].[AbonnementOpretAttempts] AS [AbonnementOpretAttempts], 

    [Limit1].[AbonnementsId] AS [AbonnementsId], 

    [Limit1].[BestemtFastEjendomsNummer] AS [BestemtFastEjendomsNummer], 

    [Limit1].[UpdateToken] AS [UpdateToken], 

    [Limit1].[FaellesEjendomIdentifikator] AS [FaellesEjendomIdentifikator], 

    [Join1].[ESRId1] AS [ESRId], 

    [Join1].[ESRId1] AS [ESRId1], 

    [Join1].[EjdId] AS [EjdId2], 

    [Join1].[Passiv] AS [Passiv], 

    [Join1].[ESRId1] AS [ESRId2], 

    [Join1].[EjdId] AS [EjdId3], 

    [Join1].[ESRId2] AS [ESRId3], 

    [Join1].[ESR_Kommune] AS [ESR_Kommune], 

    [Join1].[ESR_EjdNummer] AS [ESR_EjdNummer], 

    [Join1].[UdgaaetCognito] AS [UdgaaetCognito], 

    [Join1].[Status] AS [Status], 

    CAST(NULL AS int) AS [C2], 

    CAST(NULL AS varchar(1)) AS [C3], 

    CAST(NULL AS varchar(1)) AS [C4], 

    CAST(NULL AS int) AS [C5]

    FROM   (SELECT TOP (1000) 

        [Extent1].[EjdId] AS [EjdId], 

        [Extent1].[EjdType] AS [EjdType], 

        [Extent1].[BygningsNr] AS [BygningsNr], 

        [Extent1].[TimeshareNr] AS [TimeshareNr], 

        [Extent1].[AnpartsNr] AS [AnpartsNr], 

        [Extent1].[EjerLejNr] AS [EjerLejNr], 

        [Extent1].[Beskrivelse] AS [Beskrivelse], 

        [Extent1].[StreetBuildingIdentifier] AS [StreetBuildingIdentifier], 

        [Extent1].[EjdStatus] AS [EjdStatus], 

        [Extent1].[StatusTimestamp] AS [StatusTimestamp], 

        [Extent1].[IAbonnement] AS [IAbonnement], 

        [Extent1].[AbonnementOpretAttempts] AS [AbonnementOpretAttempts], 

        [Extent1].[AbonnementsId] AS [AbonnementsId], 

        [Extent1].[BestemtFastEjendomsNummer] AS [BestemtFastEjendomsNummer], 

        [Extent1].[UpdateToken] AS [UpdateToken], 

        [Extent1].[FaellesEjendomIdentifikator] AS [FaellesEjendomIdentifikator]

        FROM [dbo].[TinglysEjendom] AS [Extent1]

        WHERE [Extent1].[EjdStatus] = @p__linq__0 ) AS [Limit1]

    LEFT OUTER JOIN  (SELECT [Extent2].[ESRId] AS [ESRId1], [Extent2].[EjdId] AS [EjdId], [Extent2].[Passiv] AS [Passiv], [Extent3].[ESRId] AS [ESRId2], [Extent3].[ESR_Kommune] AS [ESR_Kommune], [Extent3].[ESR_EjdNummer] AS [ESR_EjdNummer], [Extent3].[UdgaaetCognito] AS [UdgaaetCognito], [Extent3].[Status] AS [Status]

        FROM  [dbo].[TinglysEjd_ESR] AS [Extent2]

        INNER JOIN [dbo].[ESR] AS [Extent3] ON [Extent2].[ESRId] = [Extent3].[ESRId] ) AS [Join1] ON [Limit1].[EjdId] = [Join1].[EjdId]

UNION ALL

    SELECT 

    2 AS [C1], 

    [Limit2].[EjdId] AS [EjdId], 

    [Limit2].[EjdId] AS [EjdId1], 

    [Limit2].[EjdType] AS [EjdType], 

    [Limit2].[BygningsNr] AS [BygningsNr], 

    [Limit2].[TimeshareNr] AS [TimeshareNr], 

    [Limit2].[AnpartsNr] AS [AnpartsNr], 

    [Limit2].[EjerLejNr] AS [EjerLejNr], 

    [Limit2].[Beskrivelse] AS [Beskrivelse], 

    [Limit2].[StreetBuildingIdentifier] AS [StreetBuildingIdentifier], 

    [Limit2].[EjdStatus] AS [EjdStatus], 

    [Limit2].[StatusTimestamp] AS [StatusTimestamp], 

    [Limit2].[IAbonnement] AS [IAbonnement], 

    [Limit2].[AbonnementOpretAttempts] AS [AbonnementOpretAttempts], 

    [Limit2].[AbonnementsId] AS [AbonnementsId], 

    [Limit2].[BestemtFastEjendomsNummer] AS [BestemtFastEjendomsNummer], 

    [Limit2].[UpdateToken] AS [UpdateToken], 

    [Limit2].[FaellesEjendomIdentifikator] AS [FaellesEjendomIdentifikator], 

    CAST(NULL AS int) AS [C2], 

    CAST(NULL AS int) AS [C3], 

    CAST(NULL AS int) AS [C4], 

    CAST(NULL AS bit) AS [C5], 

    CAST(NULL AS int) AS [C6], 

    CAST(NULL AS int) AS [C7], 

    CAST(NULL AS int) AS [C8], 

    CAST(NULL AS int) AS [C9], 

    CAST(NULL AS int) AS [C10], 

    CAST(NULL AS bit) AS [C11], 

    CAST(NULL AS varchar(1)) AS [C12], 

    [Extent5].[EjdId] AS [EjdId2], 

    [Extent5].[LandsEjerlavKode] AS [LandsEjerlavKode], 

    [Extent5].[MatrikkelNummer] AS [MatrikkelNummer], 

    [Extent5].[EjdId] AS [EjdId3]

    FROM   (SELECT TOP (1000) 

        [Extent4].[EjdId] AS [EjdId], 

        [Extent4].[EjdType] AS [EjdType], 

        [Extent4].[BygningsNr] AS [BygningsNr], 

        [Extent4].[TimeshareNr] AS [TimeshareNr], 

        [Extent4].[AnpartsNr] AS [AnpartsNr], 

        [Extent4].[EjerLejNr] AS [EjerLejNr], 

        [Extent4].[Beskrivelse] AS [Beskrivelse], 

        [Extent4].[StreetBuildingIdentifier] AS [StreetBuildingIdentifier], 

        [Extent4].[EjdStatus] AS [EjdStatus], 

        [Extent4].[StatusTimestamp] AS [StatusTimestamp], 

        [Extent4].[IAbonnement] AS [IAbonnement], 

        [Extent4].[AbonnementOpretAttempts] AS [AbonnementOpretAttempts], 

        [Extent4].[AbonnementsId] AS [AbonnementsId], 

        [Extent4].[BestemtFastEjendomsNummer] AS [BestemtFastEjendomsNummer], 

        [Extent4].[UpdateToken] AS [UpdateToken], 

        [Extent4].[FaellesEjendomIdentifikator] AS [FaellesEjendomIdentifikator]

        FROM [dbo].[TinglysEjendom] AS [Extent4]

        WHERE [Extent4].[EjdStatus] = @p__linq__0 ) AS [Limit2]

    INNER JOIN [dbo].[TingLysMatrikkel] AS [Extent5] ON [Limit2].[EjdId] = [Extent5].[EjdId]) AS [UnionAll1]

ORDER BY [UnionAll1].[EjdId1] ASC, [UnionAll1].[C1] ASC',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'HentData'

1 个答案:

答案 0 :(得分:2)

这在C#部分看起来有点不可靠。也就是说,由实体框架将其转换为执行您所要求的SQL,并且它没有做到这一点。如果还没有,可能值得报告错误。

如果仔细查看SQL,您会发现两个单独的查询使用TOP (1000)组合UNION ALL。但是,这些查询都没有使用任何ORDER BY,因此没有什么可以防止SQL Server选择一组不同的1000条记录,例如,如果与第二部分相比,它可以对查询的第一部分使用不同的索引。

您应该能够通过指定 要返回的前1000条记录来解决此问题。如果您不关心订单,只需按ID订购。