2010-08-05 170 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