EF LINQ включает в себя несколько вложенных сущностей
хорошо, у меня есть трехуровневые сущности со следующей иерархией: курс - > модуль - > глава
здесь было оригинальное заявление EF LINQ:
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters))
.Single(x => x.Id == id);
теперь я хочу включить еще один объект, называемый Lab, который связан с курсом.
Как включить объект Lab?
я попробовал следующее, Но это не сработало:
Course course = db.Courses
.Include(i => i.Modules.Select(s => s.Chapters) && i.Lab)
.Single(x => x.Id == id);
есть идеи по включению 2-й сущности?
любая часть советует или информации был бы весьма признателен. Спасибо!
5 ответов:
вы пробовали просто добавить еще один
Include:Course course = db.Courses .Include(i => i.Modules.Select(s => s.Chapters)) .Include(i => i.Lab) .Single(x => x.Id == id);ваше решение терпит неудачу, потому что
Includeне принимает логический операторInclude(i => i.Modules.Select(s => s.Chapters) && i.Lab) ^^^ ^ ^ list bool operator other listобновление Чтобы узнать больше, загрузите LinqPad и посмотреть образцы. Я думаю, что это самый быстрый способ познакомиться с Linq и Lambda.
для начала-разница между
SelectиIncludeэто то, что с выбором вы решаете что вы хотите вернуться (ака проекция). Включить это Предвыборка функция, которая сообщает Entity Framework, что вы хотите, чтобы она включала данные из других таблиц.синтаксис Include также может быть в строке. Вот так:
db.Courses .Include("Module.Chapter") .Include("Lab") .Single(x => x.Id == id);но образцы в LinqPad объясняет это лучше.
Includeявляется частью интерфейса, так что вы можете записать несколькоIncludeутверждения друг за другомdb.Courses.Include(i => i.Modules.Select(s => s.Chapters)) .Include(i => i.Lab) .Single(x => x.Id == id);
В Ядре Entity Framework (
EF.core) можно использовать.ThenIncludeдля включения следующего уровня.var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ToList();дополнительная информация:https://docs.microsoft.com/en-us/ef/core/querying/related-data
Примечание: Скажем, вам нужно несколько
ThenInclude()onblog.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();
можно написать метод расширения, как это:
/// <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; }и использовать его так даже в общей реализации:
string[] includedNavigationProperties = new string[] { "NavProp1.SubNavProp", "NavProp2" }; var query = context.Set<T>() .Include(includedNavigationProperties);