【问题标题】:Entity Framework Include returning different values for Single and Where实体框架包括为 Single 和 Where 返回不同的值
【发布时间】:2016-04-21 07:08:11
【问题描述】:

我的应用程序可用于向单个用户和包含用户集的团队组合发送消息。结构是这样的,一个Message 实体有一个Recipients 实体,而后者又具有一个User 实体列表和一个Team 实体列表。

我正在尝试使用 EF Code First 和 Linq-to-Entities 获取 Message 实体的列表,并且我想包括 RecipientsTeams 以避免稍后出现大量延迟加载请求。

奇怪的是,如果我使用 Include 子句,Teams 列表总是空的。经过一番试验,归结为:

var messages = GetAll()
    .Include(m => m.Recipients.Teams)
    .Where(m => m.Id == 123)
    .ToList();

返回一个包含一条消息的列表,其中Teams 列表为空。 (GetAll() 只返回一个IQueryable<Message>。)但是如果我这样做了

var message = GetAll()
    .Include(m => m.Recipients.Teams)
    .Single(m => m.Id == 123);

然后我收到一条消息,其中 Teams 已正确填充。

任何想法为什么会发生这种情况?

编辑:这是生成的 SQL(取自 Entity Framework Profiler)

Where 语句

SELECT *
FROM   (SELECT [Extent1].[Id]             AS [Id],
               [Extent1].[ParentRelation] AS [ParentRelation],
               [Extent1].[CreatedUtc]     AS [CreatedUtc],
               [Extent1].[Subject]        AS [Subject],
               [Extent1].[Introduction]   AS [Introduction],
               [Extent1].[Body]           AS [Body],
               [Extent1].[GlobalId]       AS [GlobalId],
               [Extent1].[Team_Id]        AS [Team_Id],
               [Extent1].[Creator_Id]     AS [Creator_Id],
               [Extent1].[Parent_Id]      AS [Parent_Id],
               [Extent1].[ReplyTo_Id]     AS [ReplyTo_Id],
               [Join1].[Id1]              AS [Id1],
               [Join1].[ToSupervisors]    AS [ToSupervisors],
               [Join1].[Organisation_Id]  AS [Organisation_Id],
               [Join1].[Id2]              AS [Id2],
               [Join4].[Id3]              AS [Id3],
               [Join4].[Name]             AS [Name],
               [Join4].[CreatedUtc]       AS [CreatedUtc1],
               [Join4].[Description]      AS [Description],
               [Join4].[Color]            AS [Color],
               [Join4].[Status]           AS [Status],
               [Join4].[Organisation_Id]  AS [Organisation_Id1],
               CASE
                 WHEN ([Join4].[Recipients_Id1] IS NULL) THEN CAST(NULL AS int)
                 ELSE 1
               END                        AS [C1]
        FROM   [dbo].[Messages] AS [Extent1]
               INNER JOIN (SELECT [Extent2].[Id]              AS [Id1],
                                  [Extent2].[ToSupervisors]   AS [ToSupervisors],
                                  [Extent2].[Organisation_Id] AS [Organisation_Id],
                                  [Extent3].[Id]              AS [Id2]
                           FROM   [dbo].[Recipients] AS [Extent2]
                                  LEFT OUTER JOIN [dbo].[MessageExtensions] AS [Extent3]
                                    ON [Extent2].[Id] = [Extent3].[Recipients_Id]) AS [Join1]
                 ON [Extent1].[Recipients_Id] = [Join1].[Id1]
               LEFT OUTER JOIN (SELECT [Extent4].[Recipients_Id]   AS [Recipients_Id1],
                                       [Extent5].[Id]              AS [Id3],
                                       [Extent5].[Name]            AS [Name],
                                       [Extent5].[CreatedUtc]      AS [CreatedUtc],
                                       [Extent5].[Description]     AS [Description],
                                       [Extent5].[Color]           AS [Color],
                                       [Extent5].[Status]          AS [Status],
                                       [Extent5].[Organisation_Id] AS [Organisation_Id],
                                       [Extent6].[Recipients_Id]   AS [Recipients_Id2]
                                FROM   [dbo].[RecipientsTeams] AS [Extent4]
                                       INNER JOIN [dbo].[Teams] AS [Extent5]
                                         ON [Extent4].[Team_Id] = [Extent5].[Id]
                                       INNER JOIN [dbo].[MessageExtensions] AS [Extent6]
                                         ON 1 = 1) AS [Join4]
                 ON ([Extent1].[Recipients_Id] = [Join4].[Recipients_Id2])
                    AND ([Extent1].[Recipients_Id] = [Join4].[Recipients_Id1])
        WHERE  11021 = [Extent1].[Id]) AS [Project1]
ORDER  BY [Project1].[Id] ASC,
          [Project1].[Id1] ASC,
          [Project1].[Id2] ASC,
          [Project1].[C1] ASC

单一陈述

SELECT *
FROM   (SELECT [Limit1].[Id1]             AS [Id],
               [Limit1].[ParentRelation]  AS [ParentRelation],
               [Limit1].[CreatedUtc]      AS [CreatedUtc],
               [Limit1].[Subject]         AS [Subject],
               [Limit1].[Introduction]    AS [Introduction],
               [Limit1].[Body1]           AS [Body],
               [Limit1].[GlobalId1]       AS [GlobalId],
               [Limit1].[Team_Id]         AS [Team_Id],
               [Limit1].[Creator_Id]      AS [Creator_Id],
               [Limit1].[Parent_Id]       AS [Parent_Id],
               [Limit1].[ReplyTo_Id]      AS [ReplyTo_Id],
               [Limit1].[Id2]             AS [Id1],
               [Limit1].[ToSupervisors]   AS [ToSupervisors],
               [Limit1].[Organisation_Id] AS [Organisation_Id],
               [Limit1].[Id3]             AS [Id2],
               [Join5].[Id4]              AS [Id3],
               [Join5].[Name]             AS [Name],
               [Join5].[CreatedUtc1]      AS [CreatedUtc1],
               [Join5].[Description]      AS [Description],
               [Join5].[Color]            AS [Color],
               [Join5].[Status]           AS [Status],
               [Join5].[Organisation_Id]  AS [Organisation_Id1],
               CASE
                 WHEN ([Join5].[Recipients_Id1] IS NULL) THEN CAST(NULL AS int)
                 ELSE 1
               END                        AS [C1]
        FROM   (SELECT TOP (2) [Extent1].[Id]             AS [Id1],
                               [Extent1].[ParentRelation] AS [ParentRelation],
                               [Extent1].[CreatedUtc]     AS [CreatedUtc],
                               [Extent1].[Subject]        AS [Subject],
                               [Extent1].[Introduction]   AS [Introduction],
                               [Extent1].[Body]           AS [Body1],
                               [Extent1].[GlobalId]       AS [GlobalId1],
                               [Extent1].[Team_Id]        AS [Team_Id],
                               [Extent1].[Creator_Id]     AS [Creator_Id],
                               [Extent1].[Parent_Id]      AS [Parent_Id],
                               [Extent1].[ReplyTo_Id]     AS [ReplyTo_Id],
                               [Join1].[Id2],
                               [Join1].[ToSupervisors],
                               [Join1].[Organisation_Id],
                               [Join1].[Id3]
                FROM   [dbo].[Messages] AS [Extent1]
                       INNER JOIN (SELECT [Extent2].[Id]              AS [Id2],
                                          [Extent2].[ToSupervisors]   AS [ToSupervisors],
                                          [Extent2].[Organisation_Id] AS [Organisation_Id],
                                          [Extent3].[Id]              AS [Id3]
                                   FROM   [dbo].[Recipients] AS [Extent2]
                                          LEFT OUTER JOIN [dbo].[MessageExtensions] AS [Extent3]
                                            ON [Extent2].[Id] = [Extent3].[Recipients_Id]) AS [Join1]
                         ON [Extent1].[Recipients_Id] = [Join1].[Id2]
                WHERE  11021 = [Extent1].[Id]) AS [Limit1]
               LEFT OUTER JOIN (SELECT [Extent4].[Recipients_Id]   AS [Recipients_Id1],
                                       [Extent5].[Id]              AS [Id4],
                                       [Extent5].[Name]            AS [Name],
                                       [Extent5].[CreatedUtc]      AS [CreatedUtc1],
                                       [Extent5].[Description]     AS [Description],
                                       [Extent5].[Color]           AS [Color],
                                       [Extent5].[Status]          AS [Status],
                                       [Extent5].[Organisation_Id] AS [Organisation_Id],
                                       [Join4].[Id5],
                                       [Join4].[Recipients_Id2]
                                FROM   [dbo].[RecipientsTeams] AS [Extent4]
                                       INNER JOIN [dbo].[Teams] AS [Extent5]
                                         ON [Extent4].[Team_Id] = [Extent5].[Id]
                                       INNER JOIN (SELECT [Extent6].[Id]            AS [Id5],
                                                          [Extent6].[Recipients_Id] AS [Recipients_Id2]
                                                   FROM   [dbo].[Messages] AS [Extent6]
                                                          LEFT OUTER JOIN [dbo].[MessageExtensions] AS [Extent7]
                                                            ON [Extent6].[Recipients_Id] = [Extent7].[Recipients_Id]) AS [Join4]
                                         ON [Extent4].[Recipients_Id] = [Join4].[Recipients_Id2]) AS [Join5]
                 ON [Limit1].[Id1] = [Join5].[Id5]) AS [Project1]
ORDER  BY [Project1].[Id] ASC,
          [Project1].[Id1] ASC,
          [Project1].[Id2] ASC,
          [Project1].[C1] ASC

当我手动运行这些查询时,我得到了相同的结果。对于WhereTeam 相关属性全部为NULL,而对于Single,它们被填充。

编辑 2GetAll 方法是存储库方法

public virtual IQueryable<T> GetAll()
{
    return Context.Set<T>();
}

TMessage

【问题讨论】:

  • 不可能。你看过进入数据库的 sql 代码吗?
  • GetAll() 方法中的代码是什么?
  • 在 SQL 语句和 GetAll 方法中编辑

标签: c# entity-framework linq-to-entities


【解决方案1】:

你可以试试这个吗? var messages = GetAll().Include(m => m.Recipients.Teams) .Where(m => m.Id == 123).Select(m=>m);

【讨论】:

  • 没有变化——结果完全一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
相关资源
最近更新 更多