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, вы можете использовать новый метод ThenInclude
query.Include(x => x.Collection)
.ThenInclude(x => x.Property);
Если я правильно вас понимаю, вы спрашиваете о включении вложенных свойств. Если это так:
.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)
или
.Include("ApplicationsWithOverrideGroup.NestedProp")
или
.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")
ядро EF: использование "ThenInclude" для загрузки уровней mutiple: Например:
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ThenInclude(author => author.Photo)
.ToList();
Я сделал небольшой помощник для Entity Framework 6 (.Net Core style), чтобы включить суб-сущности приятным образом.
сейчас в NuGet : установить-пакет 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
может значительно ускорить процесс, если вы не собираетесь на самом деле редактировать объекты и resaving.
позвольте мне четко заявить, что вы можете использовать перегрузку строк для включения вложенных уровней независимо от кратности соответствующих отношений, если вы не против использования строковых литералов:
query.Include("Collection.Property")