EF LINQ包含多个嵌套实体

Ani*_*ola 148 .net linq entity-framework asp.net-mvc-3 entity-framework-5

好的,我有三层实体,具有以下层次结构:课程 - >模块 - >章节

这是最初的EF LINQ声明:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters))
                .Single(x => x.Id == id); 
Run Code Online (Sandbox Code Playgroud)

现在,我想要包含另一个名为Lab的实体,该实体与课程相关联.

如何包含实验室实体?

我尝试了以下但它不起作用:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
                .Single(x => x.Id == id); 
Run Code Online (Sandbox Code Playgroud)

关于包含第二实体的任何想法?

任何建议或信息都将受到高度赞赏.谢谢!

Jen*_*ter 223

你试过添加另一个Include:

Course course = db.Courses
                .Include(i => i.Modules.Select(s => s.Chapters))
                .Include(i => i.Lab)
                .Single(x => x.Id == id);
Run Code Online (Sandbox Code Playgroud)

您的解决方案失败,因为Include不采用布尔运算符

Include(i => i.Modules.Select(s => s.Chapters) &&          i.Lab)
                           ^^^                  ^             ^ 
                          list           bool operator    other list
Run Code Online (Sandbox Code Playgroud)

更新 要了解更多信息,请下载LinqPad并查看示例.我认为这是熟悉Linq和Lambda的最快捷方式.

作为一个开始-之间差异SelectInclude是与一个选择,你决定什么要返回(又名投影).Include是一个Eager Loading函数,它告诉Entity Framework您希望它包含来自其他表的数据.

Include语法也可以是字符串.像这样:

           db.Courses
            .Include("Module.Chapter")
            .Include("Lab")
            .Single(x => x.Id == id);
Run Code Online (Sandbox Code Playgroud)

但是LinqPad的样本更好地解释了这一点.

  • @JoSmo你需要导入命名空间`System.Data.Enity`来访问extensionmethod.更多信息[这里](https://msdn.microsoft.com/en-us/library/gg671236%28v=vs.103%29.aspx) (5认同)
  • 只有这个对我有用:`.包括("Module.Chapter")`.知道为什么会这样吗? (2认同)

Ily*_*nov 23

Include是流畅的接口的一部分,因此您可以编写多个Include语句,每个语句跟随其他语句

 db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
           .Include(i => i.Lab)
           .Single(x => x.Id == id); 
Run Code Online (Sandbox Code Playgroud)


Nic*_* N. 22

在Entity Framework Core(EF.core)中,您可以使用.ThenInclude包含下一级别.

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
    .ToList();
Run Code Online (Sandbox Code Playgroud)

更多信息:https://docs.microsoft.com/en-us/ef/core/querying/related-data

注意: 假设您需要ThenInclude()打开多个blog.Posts,只需重复Include(blog => blog.Posts)并执行另一个操作ThenInclude(post => post.Other).

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Other)
 .ToList();
Run Code Online (Sandbox Code Playgroud)


Mar*_*son 18

你也可以试试

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢 - 字符串中的点符号非常有用 (3认同)
  • 这可能很有用,但是,不使用它的一个原因是以后易于重构:如果您在某个时刻重命名“章节”实体,则另一个示例将自动重命名。另一个原因是错误会更快被发现:在编译时,而不是运行时。 (2认同)
  • @MGOwen 我同意你的评论。但是,也可以使用:`db.Courses.Include($"{nameof(Modules)}.{nameof(Chapters)}").Single(c => c.Id == id);`。 (2认同)

Moh*_*hin 5

可以编写这样的扩展方法:

    /// <summary>
    /// Includes an array of navigation properties for the specified query 
    /// </summary>
    /// <typeparam name="T">The type of the entity</typeparam>
    /// <param name="query">The query to include navigation properties for that</param>
    /// <param name="navProperties">The array of navigation properties to include</param>
    /// <returns></returns>
    public static IQueryable<T> Include<T>(this IQueryable<T> query, params string[] navProperties)
        where T : class
    {
        foreach (var navProperty in navProperties)
            query = query.Include(navProperty);

        return query;
    }
Run Code Online (Sandbox Code Playgroud)

即使在通用实现中也像这样使用它:

string[] includedNavigationProperties = new string[] { "NavProp1.SubNavProp", "NavProp2" };

var query = context.Set<T>()
.Include(includedNavigationProperties);
Run Code Online (Sandbox Code Playgroud)