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?


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

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

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

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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.