2

我正在使用 ASP.NET MVC 2 和实体框架构建我的第一个 Web 应用程序。我正在使用存储库模式。从我在 Stack Overflow 和其他网站上收集的信息来看,似乎共识是每个域模型对象有一个控制器,每个聚合根对象有一个存储库。

我的问题是我应该如何通过聚合根存储库访问非根聚合对象。在我正在处理的示例中,有一个 Customer 模型和一个 Boat 模型。船只能与客户的 FK 引用一起存在,并且船只需要在客户的上下文中被引用。这使我相信我有这两个对象的聚合,并且客户是根。

现在在我的 Boats 控制器中,我有一个 Edit 操作方法:

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
    }
}

我的问题是如何在存储库中检索 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 访问 Boat 对我来说似乎更合理,但是我无法弄清楚如何返回单个 Boat 对象而不在 LINQ 查询中重复自己,这真的不适合我。

我知道我还有很多东西要学,所以希望你能指出我正确的方向!

谢谢!

4

2 回答 2

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
}

我认为,为您SQLCustomersRepository和您实现完全不同的 ICustomerRepositoryFakeCustomersRepository并找到对您的底层数据存储而言最佳的实现并不违反任何设计规则。

由于您似乎在 SQL-DB 中的 Boat 表上有一个主键,我肯定会利用这一点并实现第一个选项:return db.Boats.SingleOrDefault(x => x.ID == id);

但您的FakeCustomersRepository. 如果您更容易拥有一个客户列表并在每个客户的 Boats 集合中填充测试船,为什么不呢?在这种情况下,您的GetBoat实现FakeCustomersRepository可以使用您描述的第二个 LINQ 查询来实现。

请记住,MVC 中的单元测试并不打算测试您的特定存储库实现,而是测试您的业务逻辑,并且业务操作更多的是各种域对象和存储库方法调用的链。如果单个存储库方法完成了它应该做的事情(例如,如果GetBoat真的返回具有正确 ID 的船)更多的是稍后的集成测试,以证明您的数据库调用正常工作。

于 2010-08-06T12:23:48.423 回答
0

为什么你没有一个小船存储库?

如果 Boat 是 AggRoot,那么您应该有一个单独的存储库。

于 2010-08-05T19:09:37.350 回答