2009-09-09 75 views
17

我是Entity Framework和ASP.Net MVC的總新手,主要是從教程學到的,而沒有深入理解。 (我在.Net 2.0,ADO.Net和WebForms上有經驗)實體框架 - 我應該如何實例化我的「實體」對象

我目前的疑問來自於我實例化實體對象的方式。

基本上我在我的控制器,這樣做:

public class PostsController : Controller { 

    private NorthWindEntities db = new NorthWindEntities(); 

    public ActionResult Index() { 
      // Use the db object here, never explicitly Close/Dispose it 
    } 
} 

我做它喜歡這樣,因爲我發現它在某些MSDN博客似乎足夠權威的對我說,我認爲這是一個正確的方法。
但是,我覺得這很不容易。雖然它爲我節省了大量的代碼,我已經習慣了這樣做的:

using (NorthWindEntities db = new NorthWindEntities() { 
} 

在需要連接每個單獨的方法,如果該方法調用其他人會需要它,它會通過分貝爲一個參數給他們。這就是我在Linq-to-SQL存在之前用連接對象完成的所有事情。

另一件令我不安的事情是NorthWindEntities實現了IDisposable,按照慣例我應該把它稱爲Dispose()方法,而我不是。

您對此有何看法?
實體對象的實例是否正確?是否應該通過打開和關閉每個查詢來處理它的連接?
或者我應該使用using()子句顯式地處理它?

謝謝!

回答

21

控制器本身實現IDisposable。因此,您可以重寫Dispose並處理在控制器實例化時初始化的任何內容(如對象上下文)。

控制器的壽命與單個請求一樣長。因此,在一個動作中使用一個動作,併爲整個控制器提供一個對象上下文的上下文數量完全相同:1.

這兩種方法最大的區別在於該動作將在視圖呈現之前完成。因此,如果您在操作內部的using語句中創建ObjectContext,ObjectContext將在視圖呈現之前處理。所以你最好在行動完成之前從上下文中讀取任何內容。如果傳遞給視圖的模型像IQueryable那樣是一些懶惰列表,那麼在視圖呈現前您將處理上下文,當視圖嘗試枚舉IQueryable時會導致異常。相反,如果初始化Controller初始化時的ObjectContext(或者編寫延遲的初始化代碼,使其在運行操作時被初始化),並在Controller.Dispose中處理ObjectContext,那麼上下文仍然會在視圖呈現的時候到處走動。在這種情況下,將IQueryable傳遞給視圖是安全的。控制器將在視圖呈現後不久處理。

最後,如果我沒有指出讓你的控制器完全知道實體框架可能是一個壞主意,那我就會失職。研究一下你的模型和存儲庫模式的獨立程序集,讓控制器和模型交談。谷歌搜索會在這方面出現很多。

+0

好的,這是有道理的。 現在,問題是... 我做錯了嗎? 我真的需要處理實體對象嗎? 如果我不?我會「泄漏」到SQL Server的連接嗎? – 2009-09-09 19:57:14

+1

ObjectContext.Dispose不會做太多工作(請參閱Reflector)。但有理由認爲可以改變,你應該*處置它。 – 2009-09-09 20:30:24

3

你在這裏寫得很好。ObjectContext需要多長時間?所有模式和實踐書籍(如Dino Esposito的Microsoft-NET-Architecting-Applications)都告訴你DataContext不能長期存活,也不應該被緩存。

我只是想知道爲什麼沒有,在你的情況下,有一個ControllerBase類(我不知道MVC的實現,所以忍受着我)ObjectContext獲取所有控制器一次。特別想一想Identity Map Pattern,這已經由Entity Framework實施。即使您需要將另一個控制器作爲您的PostsController調用,它仍然可以使用相同的上下文並提高性能。