Ich erstelle eine wpf-Anwendung, die die folgenden Funktionen implementiert:
- Nehmen Sie Benutzereingaben und lesen Sie Daten aus Datenbanken
- Führen Sie einige Berechnungen durch
- Präsentieren Sie es dem Benutzer in mehreren Arten von Ansichten und schreiben Sie Änderungen zurück in db
Vorgeschlagene Architektur: Datenbank -> Entity Framework -> Repository -> Geschäftslogik -> Datendienst -> ViewModel
Gründe für die Verwendung dieser Architektur: Mehrere in der Anwendung vorhandene Szenarien (mehrere Ansichten) und mehrere Datenbanken. Daher bin ich bereit, das Repository in der Mitte für die Abstraktion zu verwenden.
Eine Einschränkung ist, dass der Kontext langlebig ist, wenn das Repository implementiert wird. Um dies zu überwinden, ist es in Ordnung, in jeder der Rohmethoden einen Kontext zu erstellen und diese in einem using () -Block zu entsorgen.
Sie können gerne alternative Ansätze vorschlagen.
c#
design
architecture
wpf
Skyuppercut
quelle
quelle
Antworten:
Verwenden Sie ein DbContext-Objekt pro Datenzugriff oder Transaktion.
DbContext
ist ein leichtes Objekt; Es kann einmal pro Geschäftsvorfall verwendet werden. Wenn SieDbContext
einen Singleton erstellen und in der gesamten Anwendung wiederverwenden, kann dies zu anderen Problemen führen, z. B. zu Problemen mit Parallelität und Speicherverlust.DbContext
implementiert im Wesentlichen eine Arbeitseinheit. Behandle es entsprechend.Entsorgen Sie keine DbContext-Objekte.
Obwohl die
DbContext
GeräteIDisposable
, sollten Sie sie nicht manuell entsorgen oder in eineusing
Anweisung einschließen.DbContext
verwaltet sein eigenes Leben; Wenn Ihre Datenzugriffsanforderung abgeschlossen ist,DbContext
wird die Datenbankverbindung automatisch für Sie geschlossen.Um zu verstehen, warum dies der Fall ist, überlegen Sie, was passiert, wenn Sie eine Linq-Anweisung für eine Entitätssammlung von a ausführen
DbContext
. Wenn Sie einen Lazy-Laden RückkehrIQueryable
aus der Datenzugriffsmethode, stehen Sie eine Pipeline bis der , bis der Client nicht tatsächlich ausgeführt wird , einige Daten von ihm zwingt (durch den AufrufFirstOrDefault()
,ToList()
oder über sie iterieren).Weiterführende
Literatur Muss ich Dispose () für meine DbContext-Objekte immer aufrufen?
Warum sollten Sie nicht Singleton Datacontexts in Entity Framework verwenden ,
Rückkehr
IEnumerable<T>
gegenIQueryable<T>
Rückkehr sollte Repositorys
IQueryable
?quelle
using
Blöcken zu machen ? Oder denke ich nur nicht an einen Fall, in dem die Verwendung eines IQueryable, wie Sie meinen, die Mühe wert wäre?DbContext
ist für die Verwaltung seiner eigenen Lebensdauer verantwortlich. Mein Vorschlag ist, es das tun zu lassen; es wird funktionieren, ob SieIQueryable
oder verwendenIEnumerable
. Der offensichtlichste Anwendungsfall, den ich mir beim verzögerten Laden vorstellen kann, ist der, bei dem Sie ein ViewModel-Objekt mit einer zugehörigen Sammlung zurückgeben, die Sammlung jedoch nie (oder nur teilweise) verwendet wird.IQueryable
So können Sie die Kosten für das Abrufen nicht verwendeter Datensätze vermeiden.Idealerweise sollte der Kontext für eine einzelne Transaktion initialisiert und beendet werden. In Ihrem Fall sollte der Kontext in Business Logic instanziiert und zum Lesen / Schreiben von Daten an das Repository weitergeleitet werden.
quelle
Wenn Sie DbContext für jede Methode in Ihrer Anwendung aufrufen, tritt ein Speicherverlust auf. Verwenden Sie eine einzelne Instanz des DbContext. Siehe den Kommentar im folgenden Beispiel:
quelle