Fragen zur Lebensdauer des Entity-Framework-Kontexts
Habe ich einige Fragen über die gewünschte Lebensdauer eines Entity Framework-Kontext in einem ASP.NET MVC-Anwendung. Ist es nicht am besten, um den Kontext am Leben für die kürzeste Zeit möglich?
Betrachten Sie die folgenden controller-action:
public ActionResult Index()
{
IEnumerable<MyTable> model;
using (var context = new MyEntities())
{
model = context.MyTable;
}
return View(model);
}
Den code oben funktioniert nicht, da das Entity Framework Kontext mehr Spielraum, während die Ansicht rendert die Seite. Wie würden andere Struktur der obige code?
InformationsquelleAutor der Frage Jonathan Wood | 2012-05-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Let ' s get umstritten!
Ich bin nicht einverstanden mit der Allgemeinen MVC + EF Konsens, dass Sie mit einem Kontext lebendig während der gesamten Anfrage ist eine gute Sache für eine Reihe von Gründen:
Geringe performance-Steigerung
Weißt du, wie teuer das erstellen einer neuen Datenbank-Kontext ist? Naja... "Ein DataContext ist leicht und ist nicht aufwendig zu erstellen" das ist aus MSDN
Holen Sie sich die IoC-falsch und es wird scheinen in Ordnung.. bis Sie live gehen
Wenn Sie Ihren IoC-container zur Entsorgung Ihres Kontext für Sie und Sie bekommen es falsch ist, Sie wirklich, wirklich falsch. Ich habe zweimal jetzt gesehen massive memory leaks erzeugt aus einem IoC-container nicht immer die Entsorgung von Kontext-richtig. Sie wird nicht begreifen, dass Sie es eingerichtet haben falsch, bis Sie Ihren Server starten, Krümelung, während ein normales Niveau von gleichzeitigen Benutzern. Es wird nicht passieren, in der Entwicklung, so tun, einige Last-tests!
Zufälligen lazy loading
Kehren Sie ein IQueryable Ihrer letzten Artikel, so dass Sie können Sie Liste auf Ihrer homepage. Einen Tag jemand anderes ist gefragt, um die Anzahl der Kommentare neben dem jeweiligen Artikel. So fügen Sie eine einfache Stück code zu der Ansicht, zu zeigen, die Anzahl der Kommentare so gerne...
Sieht gut aus, funktioniert gut. Aber eigentlich ist Sie nicht enthalten die Kommentare in den zurückgegebenen Daten also nun diese wird einen neuen Datenbank Aufruf für jeden Artikel in der Schleife. WÄHLEN Sie " N+1 Problem. 10 Artikel = 11 Datenbank-Aufrufe. Okay der code ist falsch, aber es ist eine einfache Fehler zu machen, so wird es geschehen.
Können Sie dies verhindern, indem Sie Schloß Ihre Rahmen nach unten in die Sie Daten-Schicht. Aber nicht den code zu brechen mit einer NullReferenceException auf den Artikel.Kommentare.Count() ? Ja, es wird, es wird also die Kraft, die Sie zum Bearbeiten der Daten Schicht, um die benötigten Daten für die View-Schicht. Dies ist, wie Sie sein sollten.
Code smell
Es ist nur etwas falsch schlagen Sie die Datenbank aus Ihrer Sicht. Sie wissen, dass ein IQueryable eigentlich nicht Treffer die Datenbank noch Recht, also vergiss das Objekt. Stellen Sie sicher, dass Ihre Datenbank getroffen wird, bevor es verlässt Sie Ihre Daten-Schicht.
So die Antwort
Dein code sollte (meiner Meinung nach), wie diese
DataLayer:
Controller:
Sobald Sie dies getan haben, und verstehen dann vielleicht, können Sie beginnen zu Experimentieren mit ein IoC-container-handle Zusammenhang aber definitiv nicht vor. Kopf meine Warnung, die ich gesehen habe zwei große Skala Fehler 🙂
Aber ehrlich gesagt machen, was du willst, die Programmierung ist Spaß und sollte eine Frage der Präferenz. Ich sage dir nur meine. Aber was immer Sie tun, beginnen Sie nicht mit IoC-Kontext pro-controller oder pro Anfrage nur, weil "alle coolen kids tun es." Tun Sie es, weil Sie wirklich wirklich Pflege darüber die Vorteile und verstehen, wie es richtig gemacht wird.
InformationsquelleAutor der Antwort BritishDeveloper
Ich Stimme mit ein Kontext pro Anfrage, wir in der Regel tun dies durch die Bindung der Kontext .InRequestScope mit Ninject, die auch wirklich funktioniert, ist:
Auch seine wirklich gute Praxis aufzählen, die so nahe an der Abfrage als möglich dh:
dies wird Ihnen helfen zu vermeiden, das die query, unbeabsichtigt aus Ihrer Sicht.
InformationsquelleAutor der Antwort Luke McGregor
Erstens, Sie sollten in Erwägung ziehen, Ihre Datenbank den Zugriff auf die eigenen Klassen.
Zweitens, meine bevorzugte Lösung ist die Verwendung "eine Kontext-Anfrage" (wenn Sie MVC, ich glaube, es ist ein Kontext pro controller).
Angefordert edit:
Haben Sie einen Blick auf diese Antwort, vielleicht hilft es dir auch. Bitte beachten Sie, ich bin mit webforms, so kann es nicht überprüfen, die in MVC im moment, aber es kann für Sie hilfreich sein oder zumindest geben Ihnen einige Hinweise. https://stackoverflow.com/a/10153406/1289283
Einige Beispiel für die Verwendung dieses dbcontext:
Dann können Sie etwas wie das hier tun:
Einfach, nicht wahr? Sie müssen nicht sorgen zu machen über die Entsorgung Ihrem Kontext mehr, Sie schreiben nur den code, den Sie wirklich brauchen.
Einige Leute gerne weiter aufzupeppen ein wenig, indem Sie hinzufügen UnitOfWork-pattern, oder vielleicht IoC Container... Aber ich mag diesen Ansatz, mehr wegen seiner Einfachheit.
InformationsquelleAutor der Antwort walther
Können Sie nutzen LINQ ist
.ToList()
Erweiterung Methode als solche:InformationsquelleAutor der Antwort Jesse C. Slicer