我刚刚目睹了一些奇怪的事情
让我们考虑这个例子
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正在内部联接
但是为什么呢?没有包含
有可能还是我不得不尝试在其他地方找到错误?
答案 0 :(得分:3)
Include
是同一LINQ语句中eager-load相关数据的指令。这不是导航属性的“声明”,您稍后将使用它进行过滤或选择。我经常看到这种混乱。让我们总结一下:
过滤数据
context.Orders
.Where(x => x.Owner.Id = 123)
.Where(x => x.Status.Name == "In progress")
...使用两个JOIN
生成SQL,并返回经过过滤的Orders
,不包含Owner
或Status
。
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
}
...返回的数据完全相同,因为Include
是ignored。如果最终结果中没有包含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
也被忽略了。