只读数据库视图如何适配仓储模式?

23

例子:您的数据库有一个名为“CustomerOrdersOnHold”的SQL视图。该视图返回特定客户和订单数据字段的混合过滤结果。您需要在应用程序中从此视图获取数据。这样的视图访问如何适应存储库模式?您会创建一个“CustomerOrdersOnHoldRepository”吗?像这样的只读视图是否被视为聚合根?

您的数据库中有一个名为“CustomerOrdersOnHold”的SQL视图,该视图返回特定客户和订单数据字段的混合过滤结果。您需要在应用程序中从此视图获取数据。在存储库模式中,访问此视图将如何适应其中需要考虑处理视图的优先级。您可以创建一个名为“CustomerOrdersOnHoldRepository”的类,负责实现从该视图中读取数据的方法。对于只读视图而言,其是否被视为聚合根要看具体情况。
3个回答

33
我建议将读取存储库分离出来,最好将其名称更改为Finder或Reader,该存储库适用于域使用,而不是查询只读数据。您可以参考这篇文章这篇文章,它们解释了Finder与Repository的使用。
我还建议将读模型与写模型架构CQRS这里分开。
这种架构允许您在数据存储和事件溯源的层面上将读模型与写模型分离。
对于中间解决方案,您可以通过仅将存储库与查找器分离来利用一些CQRS概念,而无需分离数据库。阅读这篇文章
如果要使用此类解决方案的示例(使用相同的数据库但将查找器与存储库分开),请查看此示例

我认为这是最好的答案。这种类型的数据/对象与领域无关,正如Mohamed所指出的,存储库术语与聚合/领域/事务相关联,因此使用此术语可能会产生误导。 CQRS旨在解决这个确切的问题。我之前问过一个类似的问题:https://dev59.com/nXI95IYBdhLWcg3w5iY4 - David Masters
由于提供了很棒的链接,这是一个很好的答案。这帮助我从不同和更清晰的角度查看我的代码。 - Landon Poch
如果您有一个Finder,那么如何命名“Saver”?存储库?但是存储库应该能够访问数据,也就是所谓的“查询”...如何解决这个问题? - JorgeeFG
名称为Repository。该存储库不会查询(如搜索),它只会通过ID获取对象。Finder将执行所有花哨的查询。此外,如果您遵循CQRS并具有不同的读取模型,则Finder将返回不同的对象,而Repository将返回域对象。 - Mohamed Abed
@MohamedAbed,你提供的“这篇文章”和“这个”链接已经失效。 - Saber

0

在DDD世界中,您的只读数据将被视为价值对象。

我通常会将访问价值对象的方法放置在现有仓储库中,直到创建单独的仓储库有意义为止。这类似于可能返回用于地址表单上使用的静态州列表的方法:

IAddressRepository
{
  Address GetAddress(string addressID);

  List<string> GetStates(string country);
}

那么在你的情况下,如果我有一个CustomerRepository或者OrderRepository,我应该向其中一个存储库添加一个方法吗?例如ICustomerRepository.GetCustomerOrdersOnHold(args)IOrderRepository.GetCustomerOrdersOnHold(args) - 300 baud

0

我认为像“CustomerOrdersOnHoldRepository”这样的单独存储库是可以的。存储库的接口将反映对象是只读的事实(通过不定义Save / Add / MakePersistent方法)。

来自如何编写存储库

...但还有另一种策略,我非常喜欢:多个存储库。在我们的订购示例中,我们可以拥有两个存储库:AllOrders和SurchargedOrders。 AllOrders代表系统中包含的每个订单的列表,SurchargedOrders表示其子集。

我不会称返回的对象为聚合根。聚合用于一致性、数据交换和生命周期。您的对象没有这些任何一个。它们似乎也不能被归类为值对象(“特征或属性”)。它们只是独立的类。


我原本倾向于给视图单独分配一个存储库,但是我的理解是,存储库仅操作聚合根(http://thinkddd.com/glossary/aggregate-root/)。 - 300 baud
这个规则是关于避免直接访问聚合内部部分的。你没有这些内部部分,就像你没有任何不变量和生命周期一样。从存储库返回这些对象是可以的。如果你喜欢,可以称它们为聚合根,但这可能有点误导。 - Dmitry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接