Wie stellen Sie sicher, dass Ihr Datenbankkontext ordnungsgemäß entsorgt wird, wenn Ihre Lazy Collection nicht mehr benötigt wird?

8

Ich suche hier nach einer Best-Practice-Antwort.

Angesichts der Tatsache, dass Best Practices für die Interaktion mit implementierten Klassen IDisposableüber die folgende UsingAnweisung erfolgen: Was ist die Best Practice für die Verwendung von EF Lazy Loading mit MVC?

Beispiel für eine Controller-Methode:

<HttpGet>
Public Function Schedule(ByVal id As Int64) As ActionResult

    Dim model As Schedule = Nothing
    Using database As dataContext = New dataContext
        model = (From s In database.Schedules Where s.ScheduleID = id Select s).FirstOrDefault
    End Using

    Return View(theSchedule)

End Function

In diesem Beispiel funktioniert das verzögerte Laden nicht, da die Datenbank [dataContext] zum Zeitpunkt des Eintreffens des Modells in der Ansicht entsorgt wird.

Die Frage ist also:
Was sind die besten Methoden für die Verwendung des verzögerten Ladens in MVC? Wie stellen Sie sicher, dass Ihr Datenbankkontext ordnungsgemäß entsorgt wird und keine Speicherlecks verursacht werden?

Sam Axe
quelle

Antworten:

9

Im Allgemeinen müssen Sie keine UsingAnweisungen mit Entity Framework-Datenkontexten verwenden. Faule Sammlungen sind einer der Gründe dafür. Ihr Code wäre also einfach:

<HttpGet>
Public Function Schedule(ByVal id As Int64) As ActionResult

    Dim model As Schedule = Nothing
    Dim database As dataContext = New dataContext
    model = (From s In database.Schedules Where s.ScheduleID = id Select s).FirstOrDefault

    Return View(model)

End Function

Datenkontexte in Entity Framework dienen zum Öffnen und Schließen von Verbindungen nach Bedarf und werden automatisch entsorgt, wenn das Datenkontextobjekt nicht mehr benötigt wird.

Das Standardverhalten von DbContext besteht darin, dass die zugrunde liegende Verbindung jederzeit automatisch geöffnet und geschlossen wird, wenn sie nicht mehr benötigt wird. Wenn Sie beispielsweise eine Abfrage ausführen und die Abfrageergebnisse mit "foreach" durchlaufen, wird durch den Aufruf von IEnumerable.GetEnumerator () die Verbindung geöffnet, und wenn später keine Ergebnisse mehr verfügbar sind, übernimmt "foreach" den Aufruf Entsorgen Sie den Enumerator, um die Verbindung zu schließen.

Das einzige Mal, IDisposablewenn Sie vorsichtig sein müssten, wäre Overridedas Standardverhalten des Datenkontexts.

Weiterführende Literatur

Muss ich Dispose on DBContext immer aufrufen? Nee.
Richtiges Verwalten von DbContext mit Entity Framework 6: eine ausführliche Anleitung

Robert Harvey
quelle
Ich bin nicht sicher, ob die zweite Hälfte Ihres vierten Satzes richtig ist: "und sie entsorgen sich automatisch, wenn das Datenkontextobjekt den Gültigkeitsbereich verlässt". Da der Datenkontext mit der Zeit in der Ansicht nicht mehr in den Geltungsbereich fällt, wäre der Kontext anhand Ihres Beispiels weiterhin verfügbar und hätte sich daher nicht selbst entsorgt? Vermisse ich etwas
Sam Axe
Nee. Ihr Recht; Ich war etwas schlampig in meiner Formulierung. Die korrekte Beschreibung lautet, dass der DBContext über sich selbst verfügt, wenn er nicht mehr benötigt wird. dh die faule Sammlung wird vollständig aufgezählt oder aufgegeben. Siehe meine Updates.
Robert Harvey
Vielen Dank, dass Sie sich die Zeit genommen haben, dies zu beantworten, Robert. Es wird sehr geschätzt.
Sam Axe
1
Beachten Sie, dass ein DBContext, der sich ohne usingAnweisung gut verhält, es viel schöner macht , den DBContext auf Wunsch in Abhängigkeit zu injizieren.
Robert Harvey
DI ist etwas, das ich in naher Zukunft untersuchen werde - also werde ich das berücksichtigen.
Sam Axe