Ich mache das mvcmusicstore-Übungs-Tutorial. Beim Erstellen des Gerüsts für den Album-Manager ist mir etwas aufgefallen (Hinzufügen, Löschen, Bearbeiten).
Ich möchte Code elegant schreiben, also suche ich nach einer sauberen Möglichkeit, dies zu schreiben.
Zu Ihrer Information, ich mache den Laden allgemeiner:
Alben = Artikel
Genres = Kategorien
Künstler = Marke
So wird der Index abgerufen (von MVC generiert):
var items = db.Items.Include(i => i.Category).Include(i => i.Brand);
So wird das zu löschende Element abgerufen:
Item item = db.Items.Find(id);
Der erste bringt alle Artikel zurück und füllt die Kategorie- und Markenmodelle innerhalb des Artikelmodells. Der zweite Teil füllt die Kategorie und die Marke nicht aus.
Wie kann ich den zweiten schreiben, um zu finden UND zu füllen, was sich darin befindet (vorzugsweise in einer Zeile) ... theoretisch - so etwas wie:
Item item = db.Items.Find(id).Include(i => i.Category).Include(i => i.Brand);
quelle
Antworten:
Sie müssen
Include()
zuerst ein einzelnes Objekt aus der resultierenden Abfrage verwenden und dann abrufen:quelle
Dennis 'Antwort ist
Include
undSingleOrDefault
. Letzteres geht in die Datenbank.Eine Alternative ist die Verwendung
Find
in Kombination mitLoad
zum expliziten Laden verwandter Entitäten ...Unten ein MSDN-Beispiel :
Gibt natürlich
Find
sofort zurück, ohne eine Anfrage an das Geschäft zu stellen, wenn diese Entität bereits vom Kontext geladen wurde.quelle
Find
für die Entität selbst kein Roundtrip zur Datenbank durchgeführt , wenn die Entität vorhanden ist. ABER Sie haben eine Rundreise für jede Beziehung, die SieLoad
eingehen, während dieSingleOrDefault
Kombination mitInclude
alles auf einmal lädt.Load
Funktion aufrufen , sollte die Beziehung ausgefüllt werden, wenn der Aufruf zurückkehrt. Wenn Sie alsoLoad
mehrmals für mehrere Beziehungen anrufen , wird jedes Mal eine Rundreise durchgeführt. Selbst für eine einzelne Beziehung führt dieFind
Methode zwei Roundtrips durch , wenn die Methode die Entität nicht im Speicher findet: einen fürFind
und einen fürLoad
. Aber dieInclude
.SingleOrDefault
Ansatz holt die Entität und Beziehung auf einmal, soweit ich weiß (aber ich bin nicht sicher)Sie müssen IQueryable in DbSet umwandeln
var dbSet = (DbSet<Item>) db.Set<Item>().Include("");
return dbSet.Find(id);
quelle
Hat nicht für mich gearbeitet. Aber ich habe es so gelöst.
Ich weiß nicht, ob das eine gute Lösung ist. Aber der andere, den Dennis gab, gab mir einen Fehler
.SingleOrDefault(x => x.ItemId = id);
quelle
SingleOrDefault(x => x.ItemId = id)
nur wegen des falschen Single=
statt Double==
?Es gibt keine wirklich einfache Möglichkeit, mit einem Fund zu filtern. Ich habe mir jedoch einen genauen Weg ausgedacht, um die Funktionalität zu replizieren. Beachten Sie jedoch einige Punkte für meine Lösung.
Mit dieser Lösung können Sie generisch filtern, ohne den Primärschlüssel in .net-core zu kennen
Die Suche unterscheidet sich grundlegend, da die Entität abgerufen wird, wenn sie in der Nachverfolgung vorhanden ist, bevor die Datenbank abgefragt wird.
Darüber hinaus kann es nach einem Objekt filtern, sodass der Benutzer den Primärschlüssel nicht kennen muss.
Diese Lösung ist für EntityFramework Core.
Hier sind einige Erweiterungsmethoden, die Sie hinzufügen können, um nach Primärschlüssel zu filtern
Sobald Sie diese Erweiterungsmethoden haben, können Sie wie folgt filtern:
quelle