只读数据库视图如何适应存储库模式?

Posted

技术标签:

【中文标题】只读数据库视图如何适应存储库模式?【英文标题】:How do read-only database views fit into the repository pattern? 【发布时间】:2011-11-14 00:29:24 【问题描述】:

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

【问题讨论】:

【参考方案1】:

我更喜欢分离读取存储库,最好甚至将其名称更改为 Finder 或 Reader,存储库是用于域使用而不是用于查询只读数据,您可以参考 this article 和 this 解释使用 Finder 分隔表单存储库。

我还建议将读取模型与写入模型架构分离 CQRS 和 there

即使在数据存储和事件溯源的使用方面,此架构也允许您将读取模型与写入模型分开。

对于中间解决方案,您可以利用一些 CQRS 概念,而无需通过仅将存储库与查找器分离来分离数据库的复杂性,阅读此post

对于此类解决方案的示例(使用相同的数据库,但将查找器与存储库分开)检查this sample

【讨论】:

我认为这是最好的答案。这种类型的数据/对象与域无关,正如 Mohamed 所指出的,术语存储库与聚合/域/事务相关联,因此使用该术语可能会产生误导。 CQRS 旨在解决这个确切的问题。不久前我问了一个类似的问题:***.com/questions/2098112/… 很好的答案,因为有很好的链接。这帮助我从不同且更清晰的角度查看我的代码。 如果你有一个Finder,你如何命名“Saver”?存储库?但是存储库应该能够访问数据又名“查询”......如何解决这个问题? 名称是存储库。存储库不查询(如在搜索中)它只通过 Id 获取对象。 Finder 将在哪里进行所有花哨的查询。此外,如果您确实遵循 CQRS 并具有不同的读取模型,则 Finder 将返回一个不同的对象,而 Repository 将返回域对象。 @MohamedAbed 你的“这篇文章”和“这个”链接已经失效。【参考方案2】:

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

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

IAddressRepository

  Address GetAddress(string addressID);

  List<string> GetStates(string country);

【讨论】:

所以在你的场景中,如果我有一个 CustomerRepository 或一个 OrderRepository 我会添加一个方法到这些存储库之一?即ICustomerRepository.GetCustomerOrdersOnHold(args)IOrderRepository.GetCustomerOrdersOnHold(args)?【参考方案3】:

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

来自How to write a repository:

...但是还有一个我非常喜欢的策略:multiple 存储库。在我们的订购示例中,我们没有理由拥有 两个存储库:AllOrders 和 SurchargedOrders。 AllOrders 代表 包含系统中每个订单的列表,SurchargedOrders 代表它的一个子集。

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

【讨论】:

我倾向于为视图提供自己的存储库,但是,据我了解,存储库仅在聚合根 (thinkddd.com/glossary/aggregate-root) 上运行。 这条规则是关于避免直接访问聚合的内部部分。你没有这些内部部分,就像你没有任何不变量和生命周期一样。可以从存储库中返回这些对象。如果您愿意,可以将它们称为聚合根,但这可能会产生误导。

以上是关于只读数据库视图如何适应存储库模式?的主要内容,如果未能解决你的问题,请参考以下文章

Developer工具新建oracle用户,希望新建用户能只读其他用户下的表或视图,请问权限应该如何设定?

结合 ORM、工作单元和存储库模式的主从视图

只读SAS视图(双击也是如此)

sqlite:只读数据库中的临时表/视图?

如何使用视图模型从存储库中获取数据

使用只读用户访问 SQL Server 主数据库中的系统视图