EF不会生成预期的SQL

时间:2014-10-27 06:40:31

标签: c# entity-framework ef-code-first linq-to-entities

我首先在我的程序中使用EF 6.1.2-beta1代码并在我的项目中使用以下模型(我的数据库也由EF生成):

enter image description here

public class Document
{
    public int Id { get; set; }
    public AppUser Creator { get; set; }
    public AppUser Modifier { get; set; }
}
public class AppUser
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public Party Party { get; set; }
}    
public class Party
{
    public int Id { get; set; }
    public string Name { get; set; }
}

我想写一个linq到实体查询来查找第一个Creator.Name的{​​{1}}和Modifier.Name(为简单起见,我想我想找到第一个Document) 。所以我写了以下代码:

Document

var result = context.Documents.Select(d => new{ d.Id, CreatorName = d.Creator.Party.Name, ModifierName = d.Modifier.Party.Name, }).FirstOrDefault(); 为以上查询生成以下EF

SQL

但是,正如您所见,上面的SELECT TOP (1) [Extent1].[Id] AS [Id], [Extent3].[Name] AS [Name] FROM [dbo].[Documents] AS [Extent1] LEFT OUTER JOIN [dbo].[AppUser] AS [Extent2] ON [Extent1].[Creator_Id] = [Extent2].[AppUserId] LEFT OUTER JOIN [dbo].[Parties] AS [Extent3] ON [Extent2].[Party_Id] = [Extent3].[Id] 只有一个加入SQL表,因此它只获得Party

[更新]

您可以从here

获取我的测试项目源代码

有谁知道问题出在哪里?

3 个答案:

答案 0 :(得分:1)

尝试多个联接。

var q = from d in context.Documents
        join uCreator in context.AppUsers on d.Creator.Id equals uCreator.Id
        join uModifier in context.AppUsers on d.Modifier.Id equals uModifier.Id
        select new {
          Id = d.Id,
          Creator = uCreator.Party.Name,
          Modifier = uModifier.Party.Name
        };

答案 1 :(得分:1)

一旦降级到EF 6.1.1就解决了这个问题(生成的SQL和结果是正确的) - 我认为这是EF 6.1.2 beta中的错误。

例如此命令

var result = context.Documents.Select(d =>
   new
   {
       d.Id,
       Creator = d.Creator,
       CreatorParty = d.Creator.Party,
       CreatorPartyName = d.Creator.Party.Name,
       Modifier = d.Modifier,
       ModifierParty = d.Modifier.Party,
       ModifierPartyName = d.Modifier.Party.Name
   }).FirstOrDefault();

生成SQL

SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent2].[Id] AS [Id1], 
    [Extent2].[UserId] AS [UserId], 
    [Extent2].[Party_Id] AS [Party_Id], 
    [Extent3].[Id] AS [Id2], 
    [Extent3].[Name] AS [Name], 
    [Extent4].[Id] AS [Id3], 
    [Extent4].[UserId] AS [UserId1], 
    [Extent4].[Party_Id] AS [Party_Id1]
    FROM    [dbo].[Documents] AS [Extent1]
    LEFT OUTER JOIN [dbo].[AppUsers] AS [Extent2] ON [Extent1].[Creator_Id] = [Extent2].[Id]
    LEFT OUTER JOIN [dbo].[Parties] AS [Extent3] ON [Extent2].[Party_Id] = [Extent3].[Id]
    LEFT OUTER JOIN [dbo].[AppUsers] AS [Extent4] ON [Extent1].[Modifier_Id] = [Extent4].[Id]

来自Parties的第二次Extent4加入(第二次AppUsers

[更新]

感谢 Masoud (在评论中) - EF中的这个错误已于10月20日修复。

答案 2 :(得分:0)

该查询与您提供的匿名类型不匹配,所以我认为这只是在您引用d.Creator.Party.Name并且您停止在那里登录时执行的?或者是否执行了多个查询?

尝试以下可能吗?

var doc = (from d in context.Documents
            .Include("Creator.Party").Include("Modifier.Party")
            select new
            {
                Id = d.Id,
                CreatorName = d.Creator.Party.Name,
                ModifierName = d.Modifier.Party.Name
            }).FirstOrDefault();