ASP.NET MVC 中的每個請求一個 DbContext(沒有 IOC 容器)
抱歉,如果這已經得到解答,但是如果您不使用 IOC 容器,如何保證每個請求一個實體框架 DbContext?(到目前為止,我遇到的答案都是關於 IOC 容器解決方案的。)
似乎大多數解決方案都與
HttpContext.Current.Items字典掛鉤,但是當請求完成時,如何保證 DbContext 的處置?(或者對於 EF 來說,處置不是絕對必要的DbContext嗎?)編輯
我目前正在我的控制器中實例化和處理我的 DbContext,但我在 ActionFilters 和 MembershipProvider 中也有幾個單獨的 DbContext 實例(我剛剛注意到,還有幾個驗證器)。所以,我認為集中實例化和儲存我的 DbContext 以減少成本可能是一個好主意。
我會使用 BeginRequest/EndRequest 方法,這有助於確保在請求結束時正確處理您的上下文。
protected virtual void Application_BeginRequest() { HttpContext.Current.Items["_EntityContext"] = new EntityContext(); } protected virtual void Application_EndRequest() { var entityContext = HttpContext.Current.Items["_EntityContext"] as EntityContext; if (entityContext != null) entityContext.Dispose(); }在你的 EntityContext 類中……
public class EntityContext { public static EntityContext Current { get { return HttpContext.Current.Items["_EntityContext"] as EntityContext; } } }
我知道這不是最近的問題,但無論如何我都會發布我的答案,因為我相信有人可能會覺得它很有用。
可能與許多其他人一樣,我遵循了已接受答案中提到的步驟。是的,它有效。但是,有一個問題:
每次發出請求時, BeginRequest() 和 EndRequest() 方法都會觸發,但不僅適用於 aspx 頁面,還適用於所有靜態內容!也就是說,如果您使用上面提到的程式碼並且您的頁面上有 30 張圖片,那麼您將重新實例化您的 dbcontext 30 次!
解決方案是使用包裝類來檢索上下文,如下所示:
internal static class ContextPerRequest { internal static DB1Entities Current { get { if (!HttpContext.Current.Items.Contains("myContext")) { HttpContext.Current.Items.Add("myContext", new DB1Entities()); } return HttpContext.Current.Items["myContext"] as DB1Entities; } } }然後用於處置
protected void Application_EndRequest(object sender, EventArgs e) { var entityContext = HttpContext.Current.Items["myContext"] as DB1Entities; if (entityContext != null) entityContext.Dispose(); }此修改可確保您僅在每個請求且僅在需要時實例化和處置您的上下文。選定的答案每次都會實例化上下文。
注意: DB1Entities 派生自 DbContext(由 VS 生成)。你可能想用你的上下文名稱來改變它;)
**注意 2:**在這個例子中,我只使用了一個 dbcontext。如果您需要使用多個,則需要根據需要修改此程式碼。不要把它當作世界問題的最終解決方案,因為它肯定不是最終產品。它只是為了給出一個提示,如何以一種非常簡單的方式實現它。
**注意 3:**同樣的方法也可以在不同的情況下使用,例如,當您想要共享 SqlConnection 或任何其他實例時……此解決方案不是 DbContext 對象獨有的,也不是實體框架獨有的。