Gibt es eine Möglichkeit, Ihre POCO-Klassen so zu dekorieren, dass untergeordnete Entitäten automatisch geladen werden, ohne sie Include()
jedes Mal verwenden zu müssen, wenn Sie sie laden?
Angenommen, ich habe ein Klassenauto mit komplexen Eigenschaften für Räder, Türen, Motor, Stoßstange, Fenster, Auspuff usw. Und in meiner App muss ich mein Auto von meinem DbContext an 20 verschiedenen Orten mit unterschiedlichen Abfragen usw. laden Ich möchte nicht angeben müssen, dass ich jedes Mal, wenn ich mein Auto laden möchte, alle Eigenschaften einbeziehen möchte.
ich möchte sagen
List<Car> cars = db.Car
.Where(x => c.Make == "Ford").ToList();
//NOT .Include(x => x.Wheels).Include(x => x.Doors).Include(x => x.Engine).Include(x => x.Bumper).Include(x => x.Windows)
foreach(Car car in cars)
{
//I don't want a null reference here.
String myString = car.**Bumper**.Title;
}
Kann ich meine POCO-Klasse oder in meiner irgendwie dekorieren OnModelCreating()
oder eine Konfiguration in EF festlegen, die besagt, dass beim Laden meines Autos nur alle Teile meines Autos geladen werden sollen? Ich möchte dies eifrig tun, daher verstehe ich, dass es nicht möglich ist, meine Navigationseigenschaften virtuell zu machen. Ich weiß, dass NHibernate ähnliche Funktionen unterstützt.
Ich frage mich nur, ob mir etwas fehlt. Danke im Voraus!
Prost,
Nathan
Ich mag die folgende Lösung, frage mich aber , ob ich die Aufrufe an die Erweiterungsmethoden verschachteln kann. Angenommen, ich habe eine ähnliche Situation mit Engine, in der es viele Teile gibt, die ich nicht überall einbeziehen möchte. Kann ich so etwas machen? (Ich habe noch keinen Weg gefunden, dies zu funktionieren). Auf diese Weise kann ich, wenn ich später herausfinde, dass Engine FuelInjectors benötigt, diese nur in der BuildEngine hinzufügen und muss sie nicht auch in BuildCar hinzufügen. Wie kann ich einen Anruf an eine Sammlung verschachteln, wenn ich die Anrufe verschachteln kann? Möchten Sie BuildWheel () für jedes meiner Räder in meinem BuildCar () aufrufen?
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.Include(x => x.Wheels).BuildWheel()
.Include(x => x.Doors)
.Include(x => x.Engine).BuildEngine()
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
public static IQueryable<Engine> BuildEngine(this IQueryable<Engine> query) {
return query.Include(x => x.Pistons)
.Include(x => x.Cylendars);
}
//Or to handle a collection e.g.
public static IQueryable<Wheel> BuildWheel(this IQueryable<Wheel> query) {
return query.Include(x => x.Rim)
.Include(x => x.Tire);
}
Hier ist ein weiterer sehr ähnlicher Thread für den Fall, dass er für andere in dieser Situation hilfreich ist, aber immer noch nicht in der Lage ist, die Erweiterungsmethoden als nächstes aufzurufen.
Entity Framework linq query Include () mehrere untergeordnete Entitäten
quelle
DbQuery<Car> CompleteCars { get { return ...
(Ihre langeInclude
Kette) im DbContext oder in einer Repository-Klasse zu erstellen. Wenn Sie könnten, würde das nicht die Möglichkeit ausschließen, "nackte" Autos aus der Datenbank zu holen?Antworten:
Nein, das können Sie beim Mapping nicht tun . Eine typische Problemumgehung ist die einfache Erweiterungsmethode:
Jetzt
Car
tun Sie jedes Mal, wenn Sie alle Beziehungen abfragen möchten, Folgendes :Bearbeiten:
Auf diese Weise können Sie Anrufe nicht verschachteln. Schließen Sie Arbeiten an der Kernentität ein, mit der Sie arbeiten. Diese Entität definiert die Form der Abfrage. Nach dem Aufruf arbeiten
Include(x => Wheels)
Sie also noch mitIQueryable<Car>
und können die Erweiterungsmethode für nicht aufrufenIQueryable<Engine>
. Sie müssen erneut beginnen mitCar
:und Sie werden diese Methode folgendermaßen anwenden:
Die Verwendung wird nicht aufgerufen,
Include(x => x.Wheels)
da sie automatisch hinzugefügt werden sollte, wenn Sie das eifrige Laden der verschachtelten Entitäten anfordern.Hüten Sie sich vor komplexen Abfragen, die von solch komplexen eifrigen Ladestrukturen erzeugt werden. Dies kann zu einer sehr schlechten Leistung und zu vielen doppelten Daten führen, die aus der Datenbank übertragen werden.
quelle
lazy loading
odereager loading
ich kann aus sehen hier seinelazy loading
i, eigentlich bin versucht , Produkte zu suchen , die Beziehung zu anderen Tabellen hat, was Sie denken?Hatte das gleiche Problem und sah den anderen Link, der ein
Include
Attribut erwähnte . Bei meiner Lösung wird davon ausgegangen, dass Sie ein Attribut mit dem Namen erstellt habenIncludeAttribute
. Mit der folgenden Erweiterungsmethode und Dienstprogrammmethode :quelle
Wenn Sie WIRKLICH alle Navigationseigenschaften einbeziehen müssen (Sie könnten Leistungsprobleme haben), können Sie diesen Code verwenden.
Wenn Sie auch Sammlungen eifrig laden müssen (selbst eine schlechteste Idee), können Sie die continue-Anweisung im Code löschen.
Der Kontext ist Ihr Kontext (dies, wenn Sie diesen Code in Ihren Kontext einfügen)
quelle
Als ich weiter an Lunyx 'Antwort arbeitete, fügte ich eine Überladung hinzu, damit sie mit einer Sammlung von Zeichenfolgen funktioniert (wobei eine Zeichenfolge ein Eigenschaftsname wie "propertyA" oder "propertyA.propertyOfAA" ist):
quelle