Entity Framework-включает несколько уровней свойств
метод Include () довольно хорошо работает для списков объектов. Но что, если мне нужно идти на два уровня глубже? Например, метод ниже вернет ApplicationServers с включенными свойствами, показанными здесь. Однако ApplicationsWithOverrideGroup-это еще один контейнер, который содержит другие сложные объекты. Могу ли я сделать Include() на этом свойстве? Или как я могу получить это свойство, чтобы полностью загрузить?
как он стоит сейчас, это метод:
public IEnumerable<ApplicationServer> GetAll()
{
return this.Database.ApplicationServers
.Include(x => x.ApplicationsWithOverrideGroup)
.Include(x => x.ApplicationWithGroupToForceInstallList)
.Include(x => x.CustomVariableGroups)
.ToList();
}
заполнит только свойство Enabled (ниже), а не свойства Application или CustomVariableGroup (ниже). Как мне это сделать?
public class ApplicationWithOverrideVariableGroup : EntityBase
{
public bool Enabled { get; set; }
public Application Application { get; set; }
public CustomVariableGroup CustomVariableGroup { get; set; }
}
7 ответов:
для EF 6
using System.Data.Entity; query.Include(x => x.Collection.Select(y => y.Property))посмотреть Примечания для получения дополнительных примеров.
добавьте
using System.Data.Entity;для версииIncludeэто принимает в лямбда.
если вы используете EF Core, вы можете использовать новый метод
ThenIncludequery.Include(x => x.Collection) .ThenInclude(x => x.Property);
Если я правильно вас понимаю, вы спрашиваете о включении вложенных свойств. Если так :
.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)или
.Include("ApplicationsWithOverrideGroup.NestedProp")или
.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")
EF Core: использование "ThenInclude" для загрузки нескольких уровней: Например:
var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .ToList();
Я сделал небольшой помощник для Entity Framework 6 (.Net Core style), чтобы включить суб-сущности в хорошем смысле.
теперь он находится на NuGet: Install-Package ThenInclude.Ef6 в
using System.Data.Entity; var thenInclude = context.One.Include(x => x.Twoes) .ThenInclude(x=> x.Threes) .ThenInclude(x=> x.Fours) .ThenInclude(x=> x.Fives) .ThenInclude(x => x.Sixes) .Include(x=> x.Other) .ToList();пакета доступно на GitHub.
Я также должен был использовать несколько включает и на 3-м уровне мне нужно несколько свойств
(from e in context.JobCategorySet where e.Id == id && e.AgencyId == agencyId select e) .Include(x => x.JobCategorySkillDetails) .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.DurationType)) .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RuleType)) .Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt.RateType)) .FirstOrDefaultAsync();это может кому-то помочь :)
больше примеры EFCore на MSDN показать, что вы можете сделать некоторые довольно сложные вещи с
IncludeиThenInclude.это хороший пример того, как сложно вы можете получить (это все одно утверждение!):
viewModel.Instructors = await _context.Instructors .Include(i => i.OfficeAssignment) .Include(i => i.CourseAssignments) .ThenInclude(i => i.Course) .ThenInclude(i => i.Enrollments) .ThenInclude(i => i.Student) .Include(i => i.CourseAssignments) .ThenInclude(i => i.Course) .ThenInclude(i => i.Department) .AsNoTracking() .OrderBy(i => i.LastName) .ToListAsync();смотрите, как вы можете цепь
Includeдаже послеThenIncludeи это своего рода "сбрасывает" вас обратно на уровень объекта верхнего уровня (инструкторы).вы даже можете повторить ту же коллекцию "первого уровня" (CourseAssignments) несколько раз следуют отдельные
ThenIncludesкоманды, чтобы добраться до различных дочерних объектов.обратите внимание, что ваш фактический запрос должен быть помечен в конце
IncludeилиThenIncludesцепи. Следующее не работает:var query = _context.Instructors.AsQueryable(); query.Include(i => i.OfficeAssignment); var first10Instructors = query.Take(10).ToArray();настоятельно рекомендуем вам настроить ведение журнала и убедиться, что ваши запросы не выходят из-под контроля, если вы включаете более одной или двух вещей. Важно увидеть, как это на самом деле работает - и вы заметите, что каждый отдельный "include" обычно является новым запросом чтобы избежать массивных соединений, возвращающих избыточные данные.
AsNoTrackingможет значительно ускорить работу, если вы не собираетесь на самом деле редактирования объектов и повторного сохранения.
позвольте мне четко заявить, что вы можете использовать перегрузку строк для включения вложенных уровней независимо от кратности соответствующих отношений, если вы не возражаете использовать строковые литералы:
query.Include("Collection.Property")
Comments