2011-12-18 85 views
1

這是我在控制器中的操作。在該控制器內創建和部署數據庫連接(即PhotoGalleryContext - 這是與MySql數據庫的連接)是不好的做法,而不是通過在模型中的數據訪問層中完成此操作來進行抽象。 CS類?MVC3數據上下文最佳實踐

// GET: /Admin/GetPhoto/id 
    public ActionResult GetPhoto(int id) 
    { 
     PhotoGalleryContext db = new PhotoGalleryContext(); 

     Models.PhotoGallery.Photo photo = new Models.PhotoGallery.Photo(); 
     photo = db.Photos.Where(p => p.PhotoId == id).Single(); 

     string filePath = photo.FileLocation; 

     db.Dispose();  

     byte[] byteArray; 
     try 
     { 
      byteArray = System.IO.File.ReadAllBytes(filePath); 
      return File(byteArray, "image/jpg"); 
     } 
     catch (Exception) 
     { 
      //throw; 
     } 
     return null; 
    } 
+0

你在哪裏處理db(PhotoGalleryContext)?這不是在這個例子中? – DaveShaw 2011-12-18 22:25:13

+0

複製粘貼錯誤,* editted *顯示dispose – 2011-12-18 22:26:43

回答

1

同意大衛,因爲它取決於應用程序的大小。

但是,我建議使用依賴注入來管理你的連接。

使用類似StructureMap,你可以有這樣的事情:

For<PhotoGalleryContext>() 
    .HybridHttpOrThreadLocalScoped 
    .Use<PhotoGalleryContext>(); 

翻譯爲:

當一些要求一個PhotoGalleryContext,給它一個新的PhotoGalleryContext那是HTTP作用域(在請求開始時創建,在末尾處處理)。

這樣,StructureMap會自動爲你打開/關閉連接。

那麼你的控制器是這樣的:

private readonly PhotoGalleryContext _db; 
public AdminController(PhotoGalleryContext db) 
{ 
    _db = db; 
} 

而且在動作方法,_db將是準備去你的。

幾行代碼在整個應用程序中保存大量重複使用語句。

+1

這是一個優雅的解決方案,非常感謝。 – 2011-12-18 23:51:10

+0

如果我返回一個仍在使用數據庫上下文的淺表副本的模型,它將阻止處理被調用? – 2011-12-19 01:29:50

+0

@TravisJ - 不,因爲View的渲染仍然是當前HTTP請求的一部分,*但是*,這是不好的做法。您的視圖不應該知道/關心任何數據庫連接。爲什麼模型會使用ctx的淺拷貝? – RPM1984 2011-12-19 07:07:16

2

在決定這個時你可能會考慮你的應用程序的大小。我要說的分離模式是一個最佳實踐,但對於較小的應用程序,或許你應該換行PhotoGalleryContext在使用塊:

using(PhotoGalleryContext db = new PhotoGalleryContext()) 
{ 

    Models.PhotoGallery.Photo photo = new Models.PhotoGallery.Photo(); 
    photo = db.Photos.Where(p => p.PhotoId == id).Single(); 

    string filePath = photo.FileLocation; 
    byte[] byteArray; 
    try 
    { 
     byteArray = System.IO.File.ReadAllBytes(filePath); 
     return File(byteArray, "image/jpg"); 
    } 
    catch (Exception) 
    { 
     //throw; 
    } 
    return null; 
} 
+1

如果我將它分解成模型,我是否仍然只是在像這樣的控制器內部每次都實例化PhotoGalleryManager類,然後在最後處置它?如果我的管理器包含許多不同的操作,那麼加載整個管理器類就像這樣輕量級是否會很慢? – 2011-12-18 22:31:24

+0

使用()比調用.dispose()更好嗎? – 2011-12-18 22:31:58

+1

使用()在末端大括號處調用Dispose(),imo使得代碼更加可讀一目瞭然(只要您嵌套格式化代碼)。 – danludwig 2011-12-18 23:16:31