EF Core是否独自加入?

时间:2019-06-07 12:17:39

标签: c# asp.net-core entity-framework-core npgsql

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

让我们考虑这个例子

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({{1} }),甚至发现Status正在内部联接

但是为什么呢?没有包含

有可能还是我不得不尝试在其他地方找到错误?

1 个答案:

答案 0 :(得分:3)

Include是同一LINQ语句中eager-load相关数据的指令。这不是导航属性的“声明”,您稍后将使用它进行过滤或选择。我经常看到这种混乱。让我们总结一下:

不需要包含

  • 过滤数据

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

    ...使用两个JOIN生成SQL,并返回经过过滤的Orders,不包含OwnerStatus

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

    ...返回仅包含Orders的经过过滤的Owner

  • 选择数据

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

    ...再次使用两个联接生成SQL并返回匿名类型对象,没有Owner,没有Status

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

    ...返回的数据完全相同,因为Includeignored。如果最终结果中没有包含Include d数据的数据,则Include将被忽略。

请注意,Include在类似查询中确实有效

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

即使返回了匿名类型,但其中的Order还是Owner的容器,并且包含了Owner。这在EF 6中有所不同(我猜还是在.NET Core 3.0的EF 6.3中),后者Include也被忽略了。