Come includere l'oggetto figlio di un oggetto figlio in Entity Framework 5


138

Sto usando Entity Framework 5 code firste ASP.NET MVC 3.

Sto lottando per far popolare l'oggetto figlio di un oggetto figlio. Di seguito sono le mie lezioni ..

Classe di applicazione;

public class Application
{
     // Partial list of properties

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

Classe per bambini:

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 del metodo GetAll nel repository per restituire tutte le applicazioni:

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

La classe Child contiene un riferimento alla classe ChildRelationshipType. Per lavorare con i bambini di un'applicazione avrei qualcosa del genere:

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

Qui ricevo un errore che il contesto dell'oggetto è già chiuso.

Come faccio a specificare che ogni oggetto figlio deve includere l' ChildRelationshipTypeoggetto come quello che ho fatto sopra?


Risposte:


256

Se si include la libreria, System.Data.Entityè possibile utilizzare un sovraccarico del Include()metodo che accetta un'espressione lambda anziché una stringa. È quindi possibile Select()sovrascrivere i bambini con espressioni Linq anziché stringpercorsi.

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

6
Come diceva GraemeMiller, le classi fortemente tipizzate sono migliori per la manutenibilità rispetto all'uso delle stringhe
Ryan Amies,

Quale versione è disponibile il metodo lamba? Sono bloccato su una base di codice EF 4.0 ... e non riesco a far funzionare le lamdas. Grazie per qualsiasi input.
granadaCoder

5
Funzionerà in EF 4, assicurati solo di aggiungere un riferimento aSystem.Data.Entity;
Ryan Amies,

5
A proposito - In EF 6 lo spazio dei nomi èMicrosoft.Data.Entity
Brad

Usando EF 5, non sono riuscito a ottenere .Select (x => x.Child) ma ha funzionato - 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

Con EF Core in .NET Core puoi usare la parola chiave ThenInclude:

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

Includi i bambini dalla raccolta per bambini:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);

6
Grazie!!! Davvero utile! A volte potresti avere un intellisense sbagliato, ignoralo e costruiscilo! :)
muhihsan,

Bello, stavo cercando .net core :)
Andy Clarke,

1
E se Children fosse una raccolta e dovessi includere le proprietà al suo interno?
dodbrico

Ho trovato un sovraccarico per quello. All'inizio non era ovvio.
dodbrico

1
@dodbrian Qual è stato il sovraccarico? Sto provando a nidificare. In seguito, dove il bambino è una raccolta.
Greg Hardin,

22

Ho finito per fare quanto segue e funziona:

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

76
Il modo fortemente tipizzato è migliore. Le stringhe magiche non sono buone per il refactoring
GraemeMiller

2

Un buon esempio dell'uso del modello di repository generico e dell'implementazione di una soluzione generica per questo potrebbe essere simile a questo.

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

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}

Come chiamerei il metodo sopra? potresti fornire un esempio
Jamee,

@Jamee -List <Expression <Func <PersonObject, object >>> includers = new List <Expression <Func <PersonObject, object >>> (); includers.Add (x => x.FirstName); Get <> PersonObject (includers);
gcoleman0828,

1
E la query viene da ...?
Doug Beard,

Spiacente @DougBeard, non seguendo la tua domanda.
gcoleman0828,

1
@ gcoleman0828 La variabile di query nel frammento di codice sopra. È magicamente istanziato? Da dove viene?
Doug Beard,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.