【问题标题】:IQueryable<T>.Include() gets ignoredIQueryable<T>.Include() 被忽略
【发布时间】:2014-04-11 16:20:53
【问题描述】:

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

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

一旦我动态创建了一个匿名对象,孩子们就会迷路,SQL 只包含父母的字段。子项的检索仍然是惰性的 - 它们仍然没有加载:

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

问题:

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

附言我想保留 Parent 虚拟的 Childs 属性。

【问题讨论】:

  • 为什么需要创建匿名对象?一种解决方案是在选择 var r2 = ctx.Set&lt;Parent&gt;().Include(p =&gt; p.Childs).Where(p =&gt; p.Id == 2).ToList() /* or ToArray() or something which evealutes the query */.Select(p =&gt; new { myParent = p}).ToList(); 之前运行查询

标签: c# .net linq entity-framework


【解决方案1】:

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

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

  • 使用投影(不选择整个对象,而只选择某些字段或不同的对象)
  • 使用了 group-by 或其他聚合
  • .. 可能还有更多情况,目前我不记得了。

可悲的是,我也不记得在 MSDN 上的什么地方偶然发现了“查询形状”的解释。如果我找到了,我会在这里放一个链接。

解决方案实际上很简单:只需指定“包含”部分,而不是尽早指定,而是在最终结果中指定。因此,不要在开头使用set.include(x),而是手动执行.Select( .. =&gt; new { .., x }) 以包含“x”。它也可以在分组期间工作,因为您也可以在那里进行投影。

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

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

【讨论】:

    【解决方案2】:

    当您创建匿名对象时,上下文的Parent DbSet Set&lt;Parent&gt;() 没有填充任何数据,因此Children 也不会存储在上下文中。一种解决方案是将孩子添加到匿名对象,但我不确定这会导致它们被添加到 Set&lt;Child&gt; DbSet

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      • 1970-01-01
      • 2017-12-29
      • 2016-08-10
      • 2020-12-22
      • 2012-10-05
      • 2013-09-03
      相关资源
      最近更新 更多