2014-02-24 13 views
2

我跟着MVC music store tutorial,我來到他們正在使用數據庫連接的部分(DbConnectionDbContext的子代)。我被教導要創建這樣的方法(使用包裝):在MVC中使用db連接的包裝方法

public class StoreManagerController : Controller 
{ 
    // 
    // GET: /StoreManager/ 

    public ActionResult Index() 
    { 
     using(var db = new DbConnection()) 
     { 
      var albums = db.Albums.Include(a => a.Genre).Include(a => a.Artist); 
      return View(albums.ToList()); 
     } 
    } 

    ... 
} 

但Visual Studio生成我一個控制器,它看起來像這樣:

public class StoreManagerController : Controller 
{ 
    private DbConnection db = new DbConnection(); 

    // 
    // GET: /StoreManager/ 

    public ActionResult Index() 
    { 
     var albums = db.Albums.Include(a => a.Genre).Include(a => a.Artist); 
     return View(albums.ToList()); 
    } 

    ... 
} 

我認爲,Visual Studio是沒有錯的,但爲什麼我告訴用using來包裝每種方法,以儘可能縮短連接,並讓用戶使用單獨的連接?

回答

1

這可能取決於您的應用程序的可用性;無論您是否需要持久連接,以及創建一個(以及其他各種因素)的成本。

但是對於初學者來說,你應該總是處置的連接(如在第一圖案,了一個由Visual Studio提示),然後移動到基於新的要求或性能相關的問題等圖案。

我在Visual Studio建議的選項中看到的最大問題是,您無法控制對象的生命週期,並且將它留給垃圾回收器以最終處理它。這可能會使連接資源在未確定的時間段內使用。

+0

他們的榜樣可能會提供有關Controller.Disposing(真)的重寫部署的上下文。這就是T4模板在MVC5中所做的。 – Dismissile

+0

如果是這種情況,那麼行爲可能是相似的。但是,我仍然更喜歡使用'using'語句的可讀性,而不是依賴稍微不太明顯的方法覆蓋。但是,這只是我... – rae1

+0

如果你有一個需要訪問上下文的私有方法,那麼你需要讓該方法將上下文作爲參數,或者只是將它提供給類。不過,我從不直接在我的控制器中使用上下文。 – Dismissile

2

我認爲,Visual Studio是沒有錯,但是爲什麼我會告訴每一個包裝方法使用

using(var db = new DbConnection()) 
    { 
     var albums = db.Albums.Include(a => a.Genre).Include(a => a.Artist); 
     return View(albums.ToList()); 
    } 

db範圍仍然只在大括號內。這也許是另一個目的是using關鍵字服務於C#。它定義了一個變量的範圍,在上面這種情況下,它是你的對象db

現在,如果您調試Visual Studio爲您生成的代碼,那麼您會注意到每次創建控制器類的對象時都會調用Dispose method,或者換句話說,調用一個操作方法在相應的控制器內。

的的DbContext實例始終置於由於以下原因 -

  • 正如你加載多個對象,它們的引用到內存中,上下文的內存消耗可能會迅速增加。這可能會導致性能問題。

  • 如果異常導致處於不可恢復的狀態的上下文中,整個應用程序可以終止。

  • 運行到併發相關問題的機率增加,因爲當數據查詢和更新,生長的時間之間的差距。

欲瞭解更多信息 - Reference