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

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

【问题讨论】:

    标签: domain-driven-design repository-pattern aggregateroot sql-view


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 我认为这是最好的答案。这种类型的数据/对象与域无关,正如 Mohamed 所指出的,术语存储库与聚合/域/事务相关联,因此使用该术语可能会产生误导。 CQRS 旨在解决这个确切的问题。不久前我问了一个类似的问题:stackoverflow.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) 上运行。
    • 这条规则是关于避免直接访问聚合的内部部分。你没有这些内部部分,就像你没有任何不变量和生命周期一样。可以从存储库中返回这些对象。如果您愿意,可以将它们称为聚合根,但这可能会产生误导。
    猜你喜欢
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多