2010-08-05 171 views
2

我正在使用ASP.NET MVC 2和實體框架構建我的第一個Web應用程序。我正在使用存儲庫模式。從Stack Overflow和其他網站收集的信息看來,共識是每個域模型對象有一個控制器,每個聚合根對象有一個存儲庫。ASP.NET MVC /實體框架:通過聚合根存儲庫訪問聚合對象

我的問題是我應該如何通過聚合根存儲庫訪問非根集合對象。在我處理的例子中,有一個Customer模型和一個Boat模型。船隻只能以客戶的FK參考存在,而船隻只需在客戶環境中參考。這導致我相信我有這兩個對象的聚合,並且客戶是根。

現在在我的船控制器我有一個編輯操作方法:

public class BoatsController : Controller 
{ 
    private ICustomersRepository customersRepository; 
    public BoatsController(ICustomersRepository customersRepository) 
    { 
     this.customersRepository = customersRepository; 
    } 
    public JsonResult Edit(int id, FormCollection collection) 
    { 
     var boat = customersRepository.GetBoat(id); 
     // Update boat 
    } 
} 

我的問題是我怎麼想檢索信息庫中的船對象?

public class SQLCustomersRepository : ICustomersRepository 
{ 
    DatabaseEntities db = new DatabaseEntities(); 

    public Boat GetBoat(int id) 
    { 
     return db.Boats.SingleOrDefault(x => x.ID == id); 

     // OR 

     return db.Customers.Where(x => x.Boats.Any(y => y.ID == id) 
          .Select(x => x.Boats.FirstOrDefault(y => y.ID == id); 
    } 
} 

可以接受我從客戶資料庫中引用db.Boats嗎?它似乎是最乾淨的,但這意味着我將不得不改變我的FakeCustomersRepository以獲得客戶和船的名單。

對我來說,通過db.Customers訪問船似乎更合理,但是我無法弄清楚如何返回一個單獨的船對象,而不必在LINQ查詢中重複我自己,因爲它並不適合我。

我知道我還有很多東西需要學習,所以希望你能指點我正確的方向!

謝謝!

回答

1

在我看來,你正在談論實現細節,而不是關於你的抽象接口和你的模型。你的界面看起來是這樣的:

public interface ICustomersRepository 
{ 
    //... other methods 
    Boat GetBoat(int id); 
    //... other methods 
} 

和模型是這樣的:

public class Customer 
{ 
    //... other stuff 
    ICollection<Boat> Boats; // or another collection type 
    //... other stuff 
} 

我我看來,這是不反對任何設計規則來實現ICustomerRepository完全不同的你SQLCustomersRepository和你的FakeCustomersRepository,並找到一個關於你的底層數據存儲最佳的實現。

因爲你似乎在你的SQL-DB在船上表的主鍵我肯定會利用這一點和實施的第一個選項:return db.Boats.SingleOrDefault(x => x.ID == id);

但它沒有必要有一艘船收集您的FakeCustomersRepository。如果您僅僅擁有一份客戶名單並且使用測試船爲每個客戶填充Boats集合更容易,爲什麼不呢?在這種情況下,FakeCustomersRepository中的GetBoat實現可以使用您描述的第二個LINQ查詢來實現。

請記住,MVC中的單元測試並不打算測試您的特定存儲庫實現,而是測試您的業務邏輯,而業務操作更多是各種域對象和存儲庫方法調用的鏈。如果單個存儲庫方法做它應該做的事情(例如,如果GetBoat確實返回了具有正確ID的船)更多的是後來的集成測試,以證明您的數據庫調用正常工作。

+0

感謝您的詳細回覆。因爲我是新手,所以我想確保我沒有違反一些基本規則或任何東西。 – 2010-08-07 16:44:33

0

爲什麼你沒有船庫?

如果Boat是AggRoot,那麼您應該有一個單獨的存儲庫。

+0

在特定客戶的上下文之外從不參考船。我非常肯定,這使得客戶成爲船舶和客戶聚集的根源。也許我不瞭解如何正確定義聚合根目錄? – 2010-08-05 20:28:27