gpt4 book ai didi

c# - IQueryable.Include() 被忽略

转载 作者:行者123 更新时间:2023-11-30 14:56:40 37 4
gpt4 key购买 nike

我有 ParentChild 实体,它们相互关联为 1 到 M。我需要在单个 SQL 查询中同时查询子项和父项,但是 Include 方法在某些情况下无法正常工作。
这对 ParentChild 表(通过 JOIN)进行了一次正确的查询:

var r1 =
ctx.Set<Parent>()
.Include(p => p.Childs)
.Where(p => p.Id == 1)
.ToList();

一旦我动态创建了一个匿名对象, children 就会迷路,SQL 只包含 parent 的字段。 child 的检索仍然是惰性的——他们仍然没有加载:

var r2 =
ctx.Set<Parent>()
.Include(p => p.Childs)
.Where(p => p.Id == 2)
.Select(p => new { myParent = p})
.ToList();

问题:

  1. 为什么会这样?
  2. 如何在我的 LINQ 中构建一个新的匿名对象,这样 children 就不会迷路?

附注我想保留 parent 虚拟的 Childs 属性(property)。

最佳答案

这是我所知的所有 EF 版本中的普遍问题。 EF 努力尽可能地传递 'includes',但是当“查询的形状发生变化”时,'includes' 将不可逆转地丢失。

查询的“形状”发生变化,例如:

  • 使用投影(不是选择整个对象,而是选择一些字段,或不同的对象)
  • 使用分组依据或其他聚合
  • .. 可能还有更多情况,目前我不记得了。

遗憾的是,我也不记得我在 MSDN 的哪个位置偶然发现了“查询的形状”解释。如果找到它,我会在此处放一个链接。

解决方案实际上非常简单:只需在不早的时候,而是在最终结果中指定“include”部分。因此,不是在开始时使用 set.include(x),而是执行 .Select( .. => new { .., x }) 以手动包含“x” .它在分组期间也有效,因为您也可以在那里进行投影。

但是,这不是解决方案。这是一个手动补丁/修补程序,不能解决任何问题。考虑到您可能希望通过某些接口(interface)公开一个“IQueryable<>”,您可能希望公开一个“基本查询”,其中包含一些已经包含的内容。当然,这在一般情况下是不可能的,因为如果界面的客户端进行投影或分组,他将丢失包含,他甚至不知道应该包含哪些是。对我来说,这是 EF 的一个主要缺陷。

编辑:刚找到一个:.Include in following query does not include really不是 MSDN,但同样好。

关于c# - IQueryable<T>.Include() 被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22268401/

37 4 0