So fügen Sie das untergeordnete Objekt eines untergeordneten Objekts in Entity Framework 5 ein

138

Ich benutze Entity Framework 5 code firstund ASP.NET MVC 3.

Ich kämpfe darum, das untergeordnete Objekt eines untergeordneten Objekts zum Auffüllen zu bringen. Unten sind meine Klassen ..

Anwendungsklasse;

public class Application
{
     // Partial list of properties

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

Kinderklasse:

public class Child
{
     // Partial list of properties

     public int ChildRelationshipTypeId { get; set; }

     public virtual ChildRelationshipType ChildRelationshipType { get; set; }
}

ChildRelationshipType-Klasse:

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

     public string Name { get; set; }
}

Teil der GetAll-Methode im Repository, um alle Anwendungen zurückzugeben:

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

Die Child-Klasse enthält einen Verweis auf die ChildRelationshipType-Klasse. Um mit den Kindern einer Anwendung zu arbeiten, hätte ich ungefähr Folgendes:

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

Ich erhalte hier die Fehlermeldung, dass der Objektkontext bereits geschlossen ist.

Wie gebe ich an, dass jedes untergeordnete Objekt das ChildRelationshipTypeObjekt enthalten muss, wie oben beschrieben?

Brendan Vogt
quelle
Mögliches Duplikat des Entity Framework - Mehrere Eigenschaftenebenen
einschließen

Antworten:

256

Wenn Sie die Bibliothek einschließen System.Data.Entity, können Sie eine Überladung der Include()Methode verwenden, die einen Lambda-Ausdruck anstelle einer Zeichenfolge verwendet. Sie können dann Select()über Kinder mit Linq-Ausdrücken anstatt über stringPfade.

return DatabaseContext.Applications
     .Include(a => a.Children.Select(c => c.ChildRelationshipType));
Ryan Amies
quelle
6
Wie GraemeMiller sagte, sind stark typisierte Klassen für die Wartbarkeit besser als die Verwendung von Zeichenfolgen
Ryan Amies
In welcher Version war die Lamba-Methode verfügbar? Ich stecke auf einer EF 4.0-Codebasis fest und kann die Lamdas nicht zum Laufen bringen. Vielen Dank für jede Eingabe.
GranadaCoder
5
Es wird in EF 4 funktionieren, stellen Sie einfach sicher, dass Sie einen Verweis aufSystem.Data.Entity;
Ryan Amies
5
Zu Ihrer Information - In EF 6 ist der NamespaceMicrosoft.Data.Entity
Brad
Mit EF 5 konnte ich .Select (x => x.Child) nicht erhalten, aber dies funktionierte - Entities.UserProfile savedProfile = 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

Mit EF Core in .NET Core können Sie das Schlüsselwort verwenden ThenInclude:

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

Kinder aus der Kindersammlung einbeziehen:

return DatabaseContext.Applications
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType1)
 .Include(a => a.Childrens).ThenInclude(cs => cs.ChildRelationshipType2);
Hayha
quelle
6
Vielen Dank!!! Wirklich hilfreich! Manchmal kann es sein, dass Sie eine falsche Intelligenz haben. Ignorieren Sie das einfach und bauen Sie! :)
Muhihsan
Schön, ich habe nach .net Core gesucht :)
Andy Clarke
1
Und was ist, wenn Children eine Sammlung ist und ich Eigenschaften darunter aufnehmen muss?
Dodbrian
Habe dafür eine Überlastung gefunden. War zunächst nicht offensichtlich.
Dodbrian
1
@ Dodbrian Was war die Überlastung? Ich versuche zu verschachteln. Dann einschließen, wo das Kind eine Sammlung ist.
Greg Hardin
22

Am Ende habe ich Folgendes gemacht und es funktioniert:

return DatabaseContext.Applications
     .Include("Children.ChildRelationshipType");
Brendan Vogt
quelle
76
Der stark getippte Weg ist besser. Magische Saiten sind nicht gut für das Refactoring
GraemeMiller
2

Ein gutes Beispiel für die Verwendung des generischen Repository-Musters und die Implementierung einer generischen Lösung hierfür könnte ungefähr so ​​aussehen.

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

{

    foreach (var include in includeProperties)
     {

        query = query.Include(include);
     }

        return query.ToList();
}
gcoleman0828
quelle
Wie würde ich die obige Methode aufrufen? Könnten Sie ein Beispiel geben
Jamee
@Jamee -List <Ausdruck <Func <PersonObject, Objekt >>> Includers = neue Liste <Ausdruck <Func <PersonObject, Objekt >>> (); includers.Add (x => x.FirstName); Get <PersonObject> (Einschlüsse);
gcoleman0828
1
Und Abfrage kommt von ...?
Doug Beard
Sorry @DougBeard, folge deiner Frage nicht.
gcoleman0828
1
@ gcoleman0828 Die Abfragevariable in Ihrem obigen Code-Snippet. Ist es magisch instanziiert? Woher kommt das?
Doug Beard