[英]ASP.NET MVC with EF and the Dispose Pattern
我正在用EF編寫ASP.NET MVC應用程序。 關於我的方法是否合理,我有一些疑問。 注意:我簡化了這個問題的基本結構,實際上所有東西的耦合都比較松散。
我們假設一個允許用戶更改復雜域模型屬性的視圖。 數據源自數據庫(通過EF),最后必須重新寫回。
據我了解,每個請求都會導致一個新的控制器實例被調用。 因此,我使用的是此處描述為選項2的“處置模式”,它可以確保每個請求都具有新的DbContext:
public class MyController : Controller
{
private MyContext repo = new MyContext();
protected override void Dispose(bool disposing)
{
this.repo.Dispose();
base.Dispose(disposing);
}
//more code...
}
現在,控制器上有一個public ActionResult Edit(elementId)
方法,該方法將從數據庫中獲取一個元素並顯示一個編輯器。 完成此請求后,對Dbcontext的任何引用都將消失,但是當我將其存儲在session中時 ,我仍然可以訪問從DB提取的Entity-Object。
稍后,用戶在視圖上按下“保存”按鈕。 對我的Controller的Save-method的請求再次創建了Controller的新實例,因此也創建了新的DbContext。 檢索存儲在我的會話中的實體對象,並根據用戶的輸入修改其屬性。 要將新狀態保存到數據庫,我必須將其附加到新上下文:
public void Save()
{
this.repo.MyTable.Attach(myEntity);
myEntity.Name = "New Name";
this.repo.SaveChanges();
}
僅當處置了myEntity
原始DbContext的舊Controller之后,此方法才能起作用,否則“附加”將失敗(無法將Entity附加到兩個上下文)。 我擔心我是否可以依靠這里放置的舊DbContext。
另外:我知道使用IoC框架是一種替代方法。 這將如何適用於我的情況,會有什么好處?
我認為您為了“簡化”問題而編輯了太多代碼,因此實際上掩蓋了一些重要問題。 但是,根據您發布的Save
方法,我可以很好地猜測您的問題。 您的倉庫很可能會創建自己的上下文,這是一個很大的禁忌。
為了回答您的總體問題,此處實現IDisposable
的原理與其他任何地方都相同: 擁有實現IDisposable
依賴項的任何類也應實現IDisposable
。 在這里,您的控制器實例化MyContext
,因此完成后應處置MyContext
。 就那么簡單。
但是,如果引入依賴項注入並將上下文注入到控制器中,則控制器不再擁有該上下文。 相反,DI容器將擁有它。 因此,您的控制器不能處理的情況下,因為它不擁有它。
並且,您應該在此處使用依賴項注入。 您的上下文應注入到您的存儲庫中,然后您的存儲庫應注入到您的控制器中。 這樣可以確保只有一個上下文實例,並且不會有像現在這樣遇到的問題,因為EF抱怨該實體屬於另一個上下文。
最后,我只想模仿@SteveGreene,說絕對沒有理由將您的實體存儲在會話中,實際上,您不應該出於很多原因,其中最重要的是,這將挫敗您撤離的任何努力從In Proc會話到更可靠的會話存儲。 一旦使用諸如StateServer,SQL Server,Redis等之類的東西,會話中放置的任何內容都必須可序列化,並且即使不是不可能序列化的實體也常常非常困難,因為它們經常與其他實體有很多關系,並且經常與這些實體的循環關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.