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