实体框架Include命令 - 左连接还是内连接?

40

当我调查IncludeJoin之间的区别时,我发现:

如果DB 不包含外键 - 它没有导航属性,所以最好使用Join

如果它有导航属性 - 那么使用Include。(它还可以节省一个db查询。)

但这里的一个答案引起了我的注意:

Include是作为join实现的。根据所包含的链接的空值性质,它是内连接还是左连接。

问题:

空值如何影响左/内连接?

在Sql Server中,我可以有一个Cities表和一个Persons表,一个人可以有一个NULLCityID

为什么Entity Framework决定了什么样的连接适合我?

编辑:可视化表述:

enter image description here

enter image description here

现在让我们将CityId更改为非空:

enter image description here

这是变化:

enter image description here

3个回答

17

我知道这个问题很老了,但如果有其他人像我一样使用EF Code First,我的问题出现在流畅映射中:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Parent>()
            .HasOptional(a => a.Child) /* LEFT OUTER JOIN */
            .WithMany()
            .HasForeignKey(a => a.ChildId);
    }

被翻译为LEFT OUTER JOIN,而

    modelBuilder.Entity<Parent>()
        .HasRequired(a => a.Child) /* INNER JOIN */
        .WithMany()
        .HasForeignKey(a => a.ChildId);

被翻译为内连接(INNER JOIN)


我会交换“Parent”和“Child”这两个词,因为按照惯例,“Child”通常是1:n关系中的“n”端。 - Gert Arnold

15
假设你的班级中有一个对城市或城市ID的 [Required] 约束。假设存在没有(有效)城市信息的个人记录。唯一满足 [Required] 的方法是执行内连接。
但只要数据库和模型中的约束匹配(比如 CityID INT NOT NULL),使用哪种连接方式并不重要。这应该是正常情况。
如果没有约束,你自然会期望进行左连接。

我目前没有任何可以添加所需内容的项目,我只是使用Linqpad并添加了“Include”(Linq)。 Linqpad根据空值向我显示了Left jOin / Inner Join。这就是我的问题所在。为什么会这样呢? - Royi Namir
哪种空值性,如何处理? - H H
2
在我看来很清楚明了。试着想象其他的组合,特别是非空和左连接 -> 无效的对象。 - H H
1
Henk,反复思考后,这似乎是合乎逻辑的。 - Royi Namir
1
有时需要使用LEFT JOIN而不是INNER JOIN。我有一个公司实体,其中包含联系人详细信息,地址和区域。区域是可选的(可为空)。每当我查询包括联系人,地址和区域的所有公司时,我只会得到那些地址有区域的公司。我想要所有没有区域的空区域公司。为什么EF强制我使用INNER JOIN而需要LEFT JOIN?我不想使用DefaultIfEmpty,创建一个与我的公司实体相同的新匿名实例,并手动复制每个属性,因为公司预期作为结果。 - Thanasis Ioannidis

1
  1. 如果从属实体的外键可以为空,则 Include(ThenInclude)将生成 LEFT JOIN。

  2. 如果从属实体的外键不可为空,则 Include(ThenInclude)将生成 INNER JOIN。

更多信息请阅读此文章:Entity Framework Core Include & ThenInclude Tip


并非完全正确。如果从主实体开始查询,而从属实体中的外键不可为空,则会进行外连接。如果您遵循基本规则:如果使用INNER JOIN不会导致查询根被过滤,请使用INNER JOIN,那么一切都会顺理成章。 - Gert Arnold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接