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);