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,不包含 Owner
或 Status
。
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 完全相同的数据,因为 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
也被忽略了。
我刚刚目睹了一些奇怪的事情
让我们考虑这个例子
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,不包含Owner
或Status
。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 完全相同的数据,因为
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
也被忽略了。