我看到的每个存储库模式示例都处理了一个非常简单的用例 - 一个对象类型和最基本的CRUD操作。然后,存储库经常直接插入MVC控制器。
真实世界的数据访问就是这样。真实世界的数据访问场景可能涉及对象的复杂图形和某种形式的事务包装器。例如,假设我要保存新订单。这涉及写入Order,OrderDetails,Invoice,User,History和ItemStock表。所有这一切都必须进行交易,承诺或回滚。通常我会传递IDbTransaction和IDbConnection之类的东西,并将整个操作捆绑在服务层中。
存储库模式在哪里适合?我错过了什么(也许是工作单位)?是否有比使用通常的固定博客片段更实际的存储库示例?
欣赏任何光线。
答案 0 :(得分:5)
这是一个非常有争议的话题,但这是我从自己的经历中得到的。
Repository
在聚合根目录下工作。例如,如果OrderItem
始终作为Order
的一部分被检索,并且没有自己的外部生命,那么它将被OrderRepository
加载,否则它将拥有它自己的存储库。
UnitOfWork
是一个重要的概念。假设OrderItem
是一个聚合根,并拥有自己的存储库。因此,在创建订单时,OrderManager
将在UnitOfWork
块中创建using
个工作,初始化OrderItemRepository
和OrderRepository
,然后提交。< / p>
是的,确切地说。想象一下 - 在我们的案例中 - 正在插入一个订单。这需要控制交易并在同一交易中单独输入订单和订单。这不能在存储库级别进行管理。这是存在UnitOfWork
概念的唯一原因,该概念被传递到存储库,因此它不拥有或初始化它。 UnitOfWork
通常是在业务层创建的。
答案 1 :(得分:3)
答案 2 :(得分:0)
如果你需要一个很好的全面,广泛使用的存储库模式的示例,请查看Cocoa's Core Data我意识到它不在你注意到的编程语言领域。但请注意,它不是一个O / R映射器。它是对象存储的完整抽象。没有要执行的Sql语句,虽然您可以选择使用的外部存储的格式,但您从不直接与它进行交互。
答案 3 :(得分:0)
我喜欢将存储库视为另一个抽象层。当实现的成本低于不执行实现的成本(代码维护,支持,增强等)时,您应该只添加抽象层。
请记住,purpose of the repository pattern用于分离检索数据的逻辑(CRUD),并将其从作用于模型的业务逻辑映射到实体模型。这通常最终会在现实世界中看起来像是某种形式的业务实体,它抽象出底层的物理数据模型。
就您的交易问题而言,是的,这与Unit of Work pattern有关。由于您提到了服务,我建议您不要将您的连接传递给各种数据访问类/方法,而是允许WCF使用自动登记来管理您的事务。 Here is an extract {强烈推荐}的Juval Lowy's WCF book,解释了此交易管理方法的方式和原因。
因此,为了回答您的问题,存储库模式适合抽象物理数据模型并将CRUD /映射与业务逻辑分离。