Вопрос по entity-framework, c# – Entity Framework - включает несколько уровней свойств

294

Метод Include () хорошо работает для списков объектов. Но что, если мне нужно пройти два уровня? Например, метод ниже вернет ApplicationServers с включенными свойствами, показанными здесь. Однако ApplicationsWithOverrideGroup - это другой контейнер, который содержит другие сложные объекты. Могу ли я сделать функцию Include () для этого свойства? Или как я могу получить это свойство для полной загрузки?

As it stands now, this method:

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; }
}
@BobHorn, у меня та же проблема. В моем случае, вложенность идет глубоко в несколько слоев, мне удалось сделать то, что вы указали. В сгенерированном SQL я мог видеть, что все столбцы возвращаются с разными псевдонимами, как c1, c2 и так далее. Мой вопрос заключается в том, как я могу сформировать вложенную коллекцию DTO из всех моих включений :(. Может быть, вы можете взять сам пример выше, так как мы возвращаем все столбцы без какого-либо пользовательского DTO (который сам по себе является коллекцией DTO & apos)? с); TechQuery
Привет, почему я получаю исключениеExpression must be a member expression когда я пытаюсь это сделать: включить коллекцию, а затем коллекцию на один уровень ниже:query.Include(e => e.Level1Collection.Select(l1 => l1.Level2Collection)). Joe.wang

Ваш Ответ

7   ответов
559

For EF 6


query.Include(x => x.Collection.Select(y => y.Property))

Увидетьзамечания для большего количества примеров.

Обязательно добавьте чтобы получить версиюInclude это берет в лямбду.

For EF Core

Используйте новый методThenInclude

query.Include(x => x.Collection)
     .ThenInclude(x => x.Property);
Я не могу использовать ваши правки, потому что ApplicationsWithOverrideGroup - это список. Приложение - это свойство каждого элемента в списке, а не самого списка. Bob Horn
@ Адем тебе нужно позвонитьInclude для каждого свойства:Db.States.Include(state => state.Cities.Select(city => city.Customers).Include(state => state.Cities.Select(city => city.Vendors)
Я не могу сделать Include () для ApplicationsWithOverrideGroup. Он не отображается в значении intellisense. Bob Horn
Аааа, но та ссылка, которую вы предоставили, кажется, дает ответ. Позвольте мне попробовать это: включить коллекцию, а затем коллекцию на один уровень ниже: query.Include (e = & gt; e.Level1Collection.Select (l1 = & gt; l1.Level2Collection)). Bob Horn
Не забудьте включить System.Data.Entity в употребления. В противном случае Intellisense предоставит вам только версию метода (строка пути).
2

что вы можете использовать перегрузку строки для включения вложенных уровней независимо от кратности соответствующих отношений, если вы не возражаете против использования строковых литералов:

query.Include("Collection.Property")
36

EF Core:  ThenInclude & quot; загрузить несколько уровней: Например:

var blogs = context.Blogs
    .Include(blog => blog.Posts)
        .ThenInclude(post => post.Author)
        .ThenInclude(author => author.Photo)
    .ToList();
К вашему сведению: VS2017 Intellisense не работал для .ThenInclude. Просто введите его так, как вы думаете, и подсветка ошибок должна исчезнуть.
Похоже, это только EF Core
Я хочу подчеркнуть комментарий @JohnWrensby: Intellisense иногда может занять особенно много времени для обработки ThenInclude, это может быть довольно запутанным для новых пользователей. У меня также были случаи, когда простое лямбда-выражение «Включить» обрабатывалось неправильно, пока вы просто не набрали его и не скомпилировали, игнорируя «ошибки». показано в VS.
55

вы спрашиваете о включении вложенных свойств. Если так :

.Include(x => x.ApplicationsWithOverrideGroup.NestedProp)

или же

.Include("ApplicationsWithOverrideGroup.NestedProp")  

или же

.Include($"{nameof(ApplicationsWithOverrideGroup)}.{nameof(NestedProp)}")  
Не забудьте включитьSystem.Data.Entity в употреблениях. В противном случае Intellisense даст вам толькоInclude(string path) версия метода.
Спасибо, я могу попробовать это. Я надеялся, что смогу держать вещи строго напечатанными и избежать строковых литералов. Но если это так, как это должно быть сделано ... Bob Horn
Вы были близки Я, возможно, не ясно, что ApplicationsWithOverrideGroup был список. Спасибо за помощь! Bob Horn
@Judo, у меня та же проблема .. В моем случае, вложенность идет глубоко в несколько слоев, мне удалось сделать включение, которое вы указали. В сгенерированном SQL я мог видеть, что все столбцы возвращаются с разными псевдонимами, как c1, c2 и так далее. Мой вопрос заключается в том, как я могу сформировать вложенную коллекцию DTO из всех моих включений :(. Может быть, вы можете взять сам пример выше, так как мы возвращаем все столбцы без какого-либо пользовательского DTO (который сам по себе является коллекцией DTO & apos)? с);
9

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

Настоятельно рекомендую настроить ведение журнала и убедиться, что ваши запросы не вышли из-под контроля, если вы включаете более одной или двух вещей. Важно видеть, как это на самом деле работает, и вы заметите, что каждое отдельное включает и включает. обычно это новый запрос, чтобы избежать массивных объединений, возвращающих избыточные данные.

AsNoTracking может значительно ускорить процесс, если вы не собираетесь на самом деле редактировать объекты и сохранять их.

Есть ли способ получить и зачисление, и зачисление в департаменты без повторного. Включая назначение курса и курса? (До сих пор кажется, что Api может пойти глубже с .ThenInclude или вернуться на верхний уровень с помощью .Include, но ничего не остается на том же уровне?)
Если вы хотите ленивой загрузки, следите за обновлениями для EF Core 2.1blogs.msdn.microsoft.com/dotnet/2018/02/02/… но если вы просто хотите загрузить больше на том же уровне, я думаю, что это дизайн. Я не уверен, о чем вы думаете, - для этого не требуется много дополнительных усилий, и это значительно уменьшает то, что возвращается из базы данных. Сущность может иметь только один или два «одинакового уровня»; вещей, но это может также иметь 50 для большого проекта, будучи явным делает ваше приложение намного быстрее.
23

чтобы красиво включать под-сущности.

Сейчас на 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.

привет, у меня есть исключение во время выполнения, я не могу привести IncludableQueryable & lt; observablecollection & gt; в IncludableQueryable & lt; genericcollection & gt;
Сначала я использую db, и я изменил файл tt, чтобы получить ObservableCollections для всех моих сущностей, любая помощь приветствуется.
@ lenny32 что-нибудь знать об этом расширении?
15

и на 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();

Это может кому-то помочь :)

это можно сделать без повторения.Include(x => x.Shifts.Select(r => r.Rate).Select(rt => rt......
ну, это зависит от того, как глубоко вы хотите пойти

Похожие вопросы