簡體   English   中英

帶有EF和Dispose模式的ASP.NET MVC

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM