【问题标题】:Include Grandchildren in EF Query在 EF 查询中包括孙子
【发布时间】:2013-01-25 22:04:26
【问题描述】:

给定对象层次结构

public class Parent
{
    public int Id { get; set; }
    public virtual Child Child { get; set; }
}

public class Child
{
    public int Id { get; set; }
    public virtual GrandChild GrandChild { get; set; }
}

public class GrandChild
{
    public int Id { get; set; }
}

和数据库上下文

public class MyContext : DbContext
{
    public DbSet<Parent> Parents { get; set; }
}

可以像这样使用 Lambda 语法 (using System.Data.Entity) 包含子孙:

using (MyContext ctx = new MyContext())
{
    var hierarchy = 
        from p in ctx.Parents.Include(p => p.Child.GrandChild) select p;
}

如果类名随后发生更改,Lambda 语法可防止中断查询。但是,如果 Parent 有一个 ICollection&lt;Child&gt; 像这样:

public class Parent
{
    public int Id { get; set; }
    public virtual ICollection<Child> Children { get; set; }
}

Lambda 语法不再有效。相反,可以使用字符串语法:

var hierarchy = from p in ctx.Parents.Include("Children.GrandChild") select p;

字符串语法是唯一的选择,还是在这种情况下有其他使用 Lambda 语法的替代方法?

【问题讨论】:

  • 我不知道你可以在那里使用字符串。这对我帮助很大。

标签: entity-framework linq-to-entities


【解决方案1】:

更新: 如果您使用的是 Entity Framework Core,则应使用以下语法

var hierarchy = from p in ctx.Parents
                    .Include(p => p.Children)
                    .ThenInclude(c => c.GrandChild)
                select p;

【讨论】:

  • 注意:在我的情况下,由于某些奇怪的原因,intellisense 不会在“.ThenInclude” lambda 子句中提示我使用 Grandchild 对象,但这是一个边缘情况,intellisense 错误并且它没有没关系 - 代码仍然编译。
  • 如果您需要包含 GrandChild(又名 GrandGrandChild)的孩子怎么办?
  • @Julen 您可以对每个嵌套的子实体递归地使用 .ThenInclude,例如:Parent.Include(child).ThenInclude(GrandChild).ThenInclude(GrandGrandChild) .. 等
  • 您将如何包括两个不同的孙子,比如 GrandSon 和 GrandDaughter?以ctx.Parents.Include(p =&gt; p.Children).ThenInclude(c =&gt; c.GrandSon)... 开头的东西。您无法添加 ThenInclude(c =&gt; c.GrandDaughter),因为它会在 GrandSon 对象中查找 GrandDaughter。
  • @SimonTewsi 不幸的是,现在唯一的方法是第二次到顶层.Include,然后再和你想包括的另一个孩子一起做一次.ThenInclude
【解决方案2】:

当然可以

var hierarchy = from p in ctx.Parents
                    .Include(p => p.Children.Select(c => c.GrandChild))
                select p;

参见MSDN,标题备注,第五个项目符号。

【讨论】:

  • 要使用这样的包含方法不要忘记引用System.Data.Entity
  • 如果孙子有孩子等等,您也可以递归地为后代继续这个 Select() 模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
相关资源
最近更新 更多