C# 实体框架以一对一(可选/必需)关系生成第二个左联接

C# 实体框架以一对一(可选/必需)关系生成第二个左联接,c#,entity-framework,ef-code-first,entity-framework-4.2,C#,Entity Framework,Ef Code First,Entity Framework 4.2,我首先在EF代码中有以下模型: public class A { public int Id { get; set; } public virtual B { get; set; } } public class B { public int Id { get; set; } public virtual A { get; set; } } 我对这种关系的定义如下: modelBuilder.Entity<A>().HasKey(entity

我首先在EF代码中有以下模型:

public class A
{
    public int Id { get; set; }

    public virtual B { get; set; }
}

public class B
{
    public int Id { get; set; }

    public virtual A { get; set; }
}
我对这种关系的定义如下:

modelBuilder.Entity<A>().HasKey(entity => entity.Id);
modelBuilder.Entity<B>().HasKey(entity => entity.Id);
modelBuilder.Entity<A>()
    .HasOptional(entity => entity.B)
    .WithRequired(entity => entity.A);
SELECT
[Extent1].[Id] AS [Id],
[Extent3].[Id] AS [Id1]
FROM [dbo].[As] AS [Extent1]
LEFT OUTER JOIN [dbo].[Bs] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Bs] AS [Extent3] ON [Extent2].[Id] = [Extent3].[Id]
生成的查询如下所示:

modelBuilder.Entity<A>().HasKey(entity => entity.Id);
modelBuilder.Entity<B>().HasKey(entity => entity.Id);
modelBuilder.Entity<A>()
    .HasOptional(entity => entity.B)
    .WithRequired(entity => entity.A);
SELECT
[Extent1].[Id] AS [Id],
[Extent3].[Id] AS [Id1]
FROM [dbo].[As] AS [Extent1]
LEFT OUTER JOIN [dbo].[Bs] AS [Extent2] ON [Extent1].[Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[Bs] AS [Extent3] ON [Extent2].[Id] = [Extent3].[Id]

为什么实体框架会为这种类型的关系留下额外的(无用的)连接?

首先欢迎来到充满惊喜的实体框架的激动人心的世界(!)。我曾经面对过这种情况;当您有一对一关系时,即使您没有显式地包括相关实体,实体框架也会创建一个join语句。
在您的情况下,第一个连接来自include语句,默认情况下添加另一个左外部连接。您可以通过删除include语句并观察将包含左外部联接语句的sql输出来检查这一点。

这很有意义。我想知道它是否在不包含Include的情况下进行左连接,以便检查确保任何B对象都必须有相应的a记录,因为如果有,那就是约束错误;但至少对于显式地包括导航属性不会导致第二个join语句。EF有很多缺点,特别是与继承相关的,如果您打算使用EF,请阅读与继承相关的问题。它还有很多优点,我认为在大多数情况下,这些优点都大于缺点。@请忽略开发人员的主要缺点,Gui开发人员的主要优点:)我100%不同意这一说法。我是一名开发人员,我发现用LINQ编写查询比编写SQL要好得多。