Como incluir o objeto filho de um objeto filho no Entity Framework 5

138

Eu estou usando Entity Framework 5 code firste ASP.NET MVC 3.

Estou lutando para que o objeto filho de um objeto filho seja preenchido. Abaixo estão minhas aulas ..

Classe de aplicação;

public class Application
{
     // Partial list of properties

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

Classe da criança:

public class Child
{
     // Partial list of properties

     public int ChildRelationshipTypeId { get; set; }

     public virtual ChildRelationshipType ChildRelationshipType { get; set; }
}

Classe ChildRelationshipType:

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

     public string Name { get; set; }
}

Parte do método GetAll no repositório para retornar todos os aplicativos:

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

A classe Child contém uma referência à classe ChildRelationshipType. Para trabalhar com os filhos de um aplicativo, eu teria algo assim:

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

Eu recebo um erro aqui que o contexto do objeto já está fechado.

Como especifico que cada objeto filho deve incluir o ChildRelationshipTypeobjeto como o que fiz acima?

Brendan Vogt
fonte
Possível duplicado da Entity Framework - incluir vários níveis de Propriedades
Michael Freidgeim

Respostas:

256

Se você incluir a biblioteca, System.Data.Entitypoderá usar uma sobrecarga do Include()método que usa uma expressão lambda em vez de uma sequência. Você pode então Select()sobre filhos com expressões Linq em vez de stringcaminhos.

return DatabaseContext.Applications
     .Include(a => a.Children.Select(c => c.ChildRelationshipType));
Ryan Amies
fonte
6
Como disse GraemeMiller, aulas de rigidez são melhores para a manutenção do que usar cordas
Ryan Amies
Qual versão o método lamba foi disponibilizado? Estou preso em uma base de código EF 4.0 ... e não consigo fazer as lamdas funcionarem. Obrigado por qualquer entrada.
precisa saber é o seguinte
5
Ele vai trabalhar na EF 4, apenas certifique-se de adicionar uma referência paraSystem.Data.Entity;
Ryan Amies
5
FYI - Em EF 6 a namespace éMicrosoft.Data.Entity
Brad
Usando o EF 5, não consegui obter .Selecione (x => x.Child), mas funcionou - Entities.UserProfile storedProfile = 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);
Geovani Martinez
91

Com o EF Core no .NET Core, você pode usar a palavra ThenInclude- chave :

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

Inclua crianças da coleção infantil:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);
Hayha
fonte
6
Obrigado!!! Realmente util! Às vezes, você pode entender errado, apenas ignore isso e construa! :)
muhihsan
Bom, eu estava procurando .net core :) #
Andy Clarke
1
E se o Children for uma coleção e eu precisar incluir propriedades nela?
dodbrian
Encontrou uma sobrecarga para isso. Não era óbvio a princípio.
dodbrian
1
@dodbrian Qual foi a sobrecarga? Estou tentando aninhar .Em seguida, inclua onde a criança é uma coleção.
Greg Hardin
22

Acabei fazendo o seguinte e funciona:

return DatabaseContext.Applications
     .Include("Children.ChildRelationshipType");
Brendan Vogt
fonte
76
A maneira fortemente tipada é melhor. Cordas mágicas não são bons para refatoração
GraemeMiller
2

Um bom exemplo de uso do padrão Generic Repository e implementação de uma solução genérica para isso pode se parecer com isso.

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

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}
gcoleman0828
fonte
Como eu chamaria o método acima? você poderia dar um exemplo
Jamee 1/16
@Jamee -List <Expressão <Func <PersonObject, objeto >>> includers = new List <Expressão <Func <PersonObject, objeto >>> (); includers.Add (x => x.PrimeiroNome); Get <PersonObject> (includers);
gcoleman0828
1
E a consulta vem de ...?
Doug Beard
Desculpe @DougBeard, por não seguir sua pergunta.
gcoleman0828
1
@ gcoleman0828 A variável de consulta no seu snippet de código acima. É instanciado magicamente? De onde isso vem?
Doug Beard