EF Core 是自己加入的吗?

EF Core did join on his own?

我刚刚目睹了一些奇怪的事情

让我们考虑这个例子

publi class Order
{
    (...)
    public Status Status { get; set; }
    public Owner Owner { get; set; }
}

public class Status
{
    (...)
    public string Name { get; set; }
}

context
.Orders
.Include(x => x.Owner)
.Where(x => x.Owner.Id = 123)
.Where(x => x.Status.Name == "asdf")
.ToList();

当这段代码正常工作时,我感到很震惊 - 它只发现那些订单 status name==asdf 的所有者 Id=123 (he had orders of other type also) 而且我什至发现 Status 正在被内部连接

但是为什么呢?没有包含

是否可能,或者我必须尝试在其他地方找到错误?

Include是对同一条LINQ语句中eager-load相关数据的指令。它不是您稍后要用于过滤或选择的 "declaration" 导航属性。我经常看到这种困惑。让我们总结一下:

不需要包含
  • 过滤数据

    context.Orders
           .Where(x => x.Owner.Id = 123)
           .Where(x => x.Status.Name == "In progress")
    

    ...生成带有两个 JOIN 和 returns 过滤的 Orders 的 SQL,不包含 OwnerStatus

    context.Orders
           .Include(o => o.Owner)
           .Where(x => x.Owner.Id = 123)
           .Where(x => x.Status.Name == "In progress")
    

    ...returns 已过滤 Orders,仅包含 Owner

  • 正在选择数据

    context.Orders
           .Select(x => new
           { 
               x.Number,
               Owner = x.Owner.Name, 
               Status = x.Status.Name
           }
    

    ...再次生成 SQL 与两个连接和 returns 匿名类型对象,没有 Owner,没有 Status.

    context.Orders
           .Include(o => o.Owner)
           .Select(x => new
           { 
               x.Number,
               Owner = x.Owner.Name, 
               Status = x.Status.Name
           }
    

    ...returns 完全相同的数据,因为 Includeignored。如果最终结果中没有任何内容可以包含 Included 数据,则 Include 将被忽略。

请注意 Include 确实对

这样的查询有效
context.Orders
       .Include(o => o.Owner)
       .Select(x => new
       { 
           Order = x,
           Owner = x.Owner.Name, 
           Status = x.Status.Name
       }

虽然返回的是匿名类型,但其中的OrderOwner的容器,包含了Owner。这在 EF 6 中有所不同(我想仍然在 .NET Core 3.0 上的 EF 6.3 中),后者 Include 也被忽略了。