EF LINQ include multiple and nested entities

后端 未结 6 1151
猫巷女王i
猫巷女王i 2020-11-28 03:25

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

Here was the original EF LINQ statement:

Course course = db         


        
相关标签:
6条回答
  • 2020-11-28 03:44

    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);
    
    0 讨论(0)
  • 2020-11-28 03:52

    this is from my project

     var saleHeadBranch = await _context.SaleHeadBranch
     .Include(d => d.SaleDetailBranch)
     .ThenInclude(d => d.Item)
     .Where(d => d.BranchId == loginTkn.branchId)
     .FirstOrDefaultAsync(d => d.Id == id);
    
    0 讨论(0)
  • 2020-11-28 03:59

    Have you tried just adding another 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 Include doesn't take a boolean operator

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

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

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

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

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

    But the samples in LinqPad explains this better.

    0 讨论(0)
  • 2020-11-28 04:02

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

    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

    Note: Say you need multiple ThenInclude() on blog.Posts, just repeat the Include(blog => blog.Posts) and do another 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();
    
    0 讨论(0)
  • 2020-11-28 04:02

    Include is a part of fluent interface, so you can write multiple Include statements each following other

     db.Courses.Include(i => i.Modules.Select(s => s.Chapters))
               .Include(i => i.Lab)
               .Single(x => x.Id == id); 
    
    0 讨论(0)
  • 2020-11-28 04:08

    You can also try

    db.Courses.Include("Modules.Chapters").Single(c => c.Id == id);
    
    0 讨论(0)
提交回复
热议问题