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; }
}
588   7  

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

    Ничего не найдено.