Ich habe vor kurzem Änderungen an meiner MVC3-Anwendung vorgenommen, um die DbContext
-Objekte [1] ordnungsgemäß zu entfernen. Dies funktionierte großartig in der Entwicklung, aber sobald die Anwendung auf meinen Produktionsserver übertragen wurde, begann ich intermittierend einige lustige Ausnahmen zu bekommen, die so lange bestehen blieben, bis der AppPool recycelt wurde. Die Ausnahmen können in meinem benutzerdefinierten AuthorizeAttribute
auf Code zurückgeführt werden und sehen folgendermaßen aus:
(Das Datenbankschema sieht folgendermaßen aus: Benutzer: [Guid, String, ...], Rechte: [Guid, Int32, ...])
Es ist so, als würden einige "Drähte gekreuzt", und die Anwendung vermischt die Ergebnisse aus der Datenbank: versucht, das Right
Ergebnis als User
zu realisieren und umgekehrt.
Um die Entsorgung von DbContext
zu verwalten, gebe ich Code ein, um dies auf einer Controller-Ebene zu speichern. Wenn der Controller entsorgt wird, entsorgen wir auch DbContext
. Ich weiß, es ist Hacky, aber die AuthorizeAttribute
verwendet den gleichen Kontext über filterContext.Controller
.
Stimmt etwas nicht mit dem Umgang mit dem Objektlebenszyklus von DbContext
in diesem Herrenhaus? Gibt es irgendwelche logischen Erklärungen, warum ich die kreuz und quer verlaufenden Ausnahmen oben bekomme?
[1] Obwohl ich weiß, dass es nicht notwendig ist, DbContext
Objekte zu entsorgen, stieß ich kürzlich auf eine Reihe von Quellen, die besagen, dass es unabhängig davon Best Practice ist.
Bearbeiten (per @ MikeSWs Kommentar)
Eine Eigenschaft von AuthorizeAttribute
, die DbContext
repräsentiert, wird in der OnAuthorization
-Methode festgelegt, wenn AuthorizationContext
im Geltungsbereich ist. Diese Eigenschaft wird später in der AuthorizeCore
-Methode verwendet.
Müssen Sie den Kontext wirklich beseitigen?
Nach diesem Beitrag
Muss ich Dispose () immer auf meinen DbContext-Objekten aufrufen? Nein,
Bevor ich mit den Entwicklern im EF-Team gesprochen habe, war meine Antwort immer ein klares "natürlich!". Aber das stimmt nicht mit DbContext. Sie müssen nicht religiös sein, wenn Sie Dispose für Ihre DbContext-Objekte aufrufen. Obwohl es IDisposable implementiert, implementiert es es nur, so dass Sie in einigen Sonderfällen Dispose als eine Sicherheitsmaßnahme aufrufen können. Standardmäßig verwaltet DbContext automatisch die Verbindung für Sie.
Zuerst empfehle ich, dass Sie "wirklich" mit vertraut werden Übersicht über die ASP.NET-Anwendungslebensdauer für IIS 7.0 , da dies für ein gutes MVC-Anwendungsdesign grundlegend ist.
Versuchen Sie nun, Ihre Codebasis zu "imitieren"
Nehmen wir an, Sie haben einen ähnlichen benutzerdefinierten MembershipProvider wie hier beschrieben Ссылка
Dann würden Sie nur ein benutzerdefiniertes Authorize
-Attribut
, die Sie für einen beliebigen Controller oder eine bestimmte Aktion verwenden können
%Vor% Wenn Sie möchten, können Sie auch das Ereignis PostAuthorizeRequest
abonnieren und die Ergebnisse basierend auf einigen Kriterien verwerfen.
Wie für die DbContext
, ich habe noch nie in Ihre Situation geraten und ja pro Anfrage ist der richtige Ansatz also Sie können es im Controller oder in Ihrem Repository entsorgen.
Natürlich sollten Sie Filter verwenden und fügen Sie dann Ihren Aktionen das Attribut [AllowAnonymous] hinzu.
Tags und Links asp.net-mvc-3 dbcontext entity-framework-4 dispose