Как включить дочерний объект дочернего объекта в Entity Framework 5

138

Я использую Entity Framework 5 code firstи ASP.NET MVC 3.

Я изо всех сил пытаюсь получить дочерний объект дочернего объекта для заполнения. Ниже мои занятия ..

Класс приложения;

public class Application
{
     // Partial list of properties

     public virtual ICollection<Child> Children { get; set; }
}

Детский класс:

public class Child
{
     // Partial list of properties

     public int ChildRelationshipTypeId { get; set; }

     public virtual ChildRelationshipType ChildRelationshipType { get; set; }
}

Класс ChildRelationshipType:

public class ChildRelationshipType
{
     public int Id { get; set; }

     public string Name { get; set; }
}

Часть метода GetAll в хранилище для возврата всех приложений:

return DatabaseContext.Applications
     .Include("Children");

Класс Child содержит ссылку на класс ChildRelationshipType. Для работы с детьми приложения у меня было бы что-то вроде этого:

foreach (Child child in application.Children)
{
     string childName = child.ChildRelationshipType.Name;
}

Я получаю ошибку здесь, что контекст объекта уже закрыт.

Как мне указать, что каждый дочерний объект должен включать ChildRelationshipTypeобъект, как я делал выше?

Брендан Фогт
источник
Возможный дубликат Entity Framework - Включает несколько уровней свойств
Майкл Фрейдгейм,

Ответы:

256

Если вы включите библиотеку, System.Data.Entityвы можете использовать перегрузку Include()метода, которая принимает лямбда-выражение вместо строки. Затем вы можете использовать Select()дочерние выражения с выражениями Linq, а не stringпутями.

return DatabaseContext.Applications
     .Include(a => a.Children.Select(c => c.ChildRelationshipType));
Райан Эмис
источник
6
Как сказал GraemeMiller, строго типизированные классы лучше обслуживать, чем использовать строки
Райан Эмис
В какой версии появился метод lamba? Я застрял на EF 4.0 Codebase .. и не могу заставить работать lamdas. Спасибо за любой вклад.
granadaCoder
5
Он будет работать в EF 4, просто обязательно добавьте ссылку наSystem.Data.Entity;
Райана Эмиса
5
К вашему сведению - в EF 6 пространство именMicrosoft.Data.Entity
Брэд
Используя EF 5, я не смог получить .Select (x => x.Child), но это сработало - Entities.UserProfile StoreProfile = db.UserProfiles .Include (s => s.ShippingAddress) .Include (st => st.ShippingAddress. StateProvince) .Include (b => b.BillingAddress) .Include (bs => bs.BillingAddress.StateProvince) .FirstOrDefault (x => x.UserId == userId);
Джовани Мартинес
91

С EF Core в .NET Core вы можете использовать ключевое слово ThenInclude:

return DatabaseContext.Applications
 .Include(a => a.Children).ThenInclude(c => c.ChildRelationshipType);

Включить детей из детской коллекции:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);
Хайха
источник
6
Спасибо!!! Действительно полезно! Иногда вы можете получить неправильный смысл, просто проигнорируйте это и постройте! :)
Мухихсан
Хороший, я искал ядро ​​.net :)
Энди Кларк
1
А что, если Children - это коллекция, и мне нужно включить в нее свойства?
Додбриан
Нашел перегрузку для этого. Сначала не было очевидно.
Додбриан
1
@dodbrian В чем была перегрузка? Я пытаюсь вложить .ThenInclude, где ребенок представляет собой коллекцию.
Грег Хардин
22

Я закончил тем, что сделал следующее, и это работает:

return DatabaseContext.Applications
     .Include("Children.ChildRelationshipType");
Брендан Фогт
источник
76
Лучше строго типизированный способ. Волшебные струны не подходят для рефакторинга
GraemeMiller
2

Хороший пример использования шаблона Generic Repository и реализации универсального решения для этого может выглядеть примерно так.

public IList<TEntity> Get<TParamater>(IList<Expression<Func<TEntity, TParamater>>> includeProperties)

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}
gcoleman0828
источник
Как бы я назвал вышеуказанный метод? Не могли бы вы привести пример
Джейми
@Jamee -List <Выражение <Func <PersonObject, объект >>> include = новый список <Выражение <Func <PersonObject, объект >>> (); includeders.Add (x => x.FirstName); Get <PersonObject> (includers);
gcoleman0828
1
И запрос приходит от ...?
Даг Борода
Извините @DougBeard, не отвечаю на ваш вопрос.
gcoleman0828
1
@ gcoleman0828 Переменная запроса в вашем фрагменте кода выше. Это магически воплощено? От куда это?
Даг Борода