.net EF LINQ 包括多个和嵌套的实体

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15764572/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 12:11:34  来源:igfitidea点击:

EF LINQ include multiple and nested entities

.netasp.net-mvc-3linqentity-frameworkentity-framework-5

提问by AnimaSola

Ok, I have tri-leveled entities with the following hierarchy: Course -> Module -> Chapter

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

Here was the original EF LINQ statement:

这是原始的 EF LINQ 语句:

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

Now, I want to include another entity called Lab which is associated with a course.

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

How do I include the Lab entity?

如何包含实验室实体?

I tried the following but it didn't work:

我尝试了以下但没有奏效:

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

Any ideas on including the 2nd Entity?

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

Any piece of advise or information would be highly appreciated. Thanks!

任何一条建议或信息将不胜感激。谢谢!

回答by Jens Kloster

Have you tried just adding another Include:

您是否尝试过添加另一个Include

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

Your solution fails because Includedoesn't take a boolean operator

您的解决方案失败,因为Include没有使用布尔运算符

Include(i => i.Modules.Select(s => s.Chapters) &&          i.Lab)
                           ^^^                  ^             ^ 
                          list           bool operator    other list

UpdateTo learn more, download LinqPadand look through the samples. I think it is the quickest way to get familiar with Linq and Lambda.

更新要了解更多信息,请下载LinqPad并浏览示例。我认为这是熟悉 Linq 和 Lambda 的最快方法。

As a start - the difference between Selectand Includeis that that with a Select you decide whatyou want to return (aka projection). The Include is a Eager Loadingfunction, that tells Entity Framework that you want it to include data from other tables.

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

The Include syntax can also be in string. Like this:

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

           db.Courses
            .Include("Module.Chapter")
            .Include("Lab")
            .Single(x => x.Id == id);

But the samples in LinqPadexplains this better.

但是LinqPad 中的示例更好地解释了这一点。

回答by Nick N.

In Entity Framework Core (EF.core) you can use .ThenIncludefor including next levels.

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

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
    .ToList();

More information: https://docs.microsoft.com/en-us/ef/core/querying/related-data

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

Note:Say you need multiple ThenInclude()on blog.Posts, just repeat the Include(blog => blog.Posts)and do another ThenInclude(post => post.Other).

注意:假设您需要多个ThenInclude()on 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();

回答by Ilya Ivanov

Includeis a part of fluent interface, so you can write multiple Includestatements each following other

Include是 fluent interface 的一部分,所以你可以写多个Include语句,一个接一个

 db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
           .Include(i => i.Lab)
           .Single(x => x.Id == id); 

回答by Martin Larsson

You can also try

你也可以试试

db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);

回答by Mohsen Afshin

One may write an extension method like this:

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

    /// <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;
    }

And use it like this even in a generic implementation:

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

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

var query = context.Set<T>()
.Include(includedNavigationProperties);