【问题标题】:How to get list of aggregates using JOliviers's CommonDomain and EventStore?如何使用 JOliviers 的 CommonDomain 和 EventStore 获取聚合列表?
【发布时间】:2011-08-19 08:21:27
【问题描述】:

CommonDomain 中的存储库仅公开“GetById()”。例如,如果我的 Handler 需要客户列表,该怎么办?

【问题讨论】:

    标签: cqrs event-sourcing neventstore commondomain


    【解决方案1】:

    从表面上看,如果您需要对多个聚合执行操作,您只需在命令中提供每个聚合的 ID(客户端将从查询端获取),然后从存储库。

    但是,查看您的一个 cmets 以响应另一个答案,我发现您实际上指的是 基于集合的验证。

    这个问题引起了很多关于如何做到这一点的争论,Greg Young has written an blog post on it.

    经典问题是“如何在处理我的“CreateUserCommand”时检查用户名是否未被使用。我相信建议的方法是假设客户端已经通过在发出命令之前询问查询方来完成此检查。创建用户聚合时,UserCreatedEvent 将由查询端引发和处理。在这里,插入查询将失败(由于数据库中的检查或唯一约束),并且将发出补偿命令,该命令将删除新创建的聚合并可能通过电子邮件通知用户用户名已被占用。

    重点是,您假设客户已经完成了检查。我知道这种方法一开始很难掌握 - 但这是最终一致性的本质。

    您可能还想阅读this 其他类似的问题,其中包含来自Udi Dahan 的一些明智的话。

    【讨论】:

    • 很好的答案,你是对的:这很难掌握。尤其是关于做客户端补偿的事情,它感觉是不对的:)。考虑您提供的链接中的示例,其中新用户必须是唯一的。进行客户端补偿仅在 CQRS-ES(无写入数据库)中有效。如果它是一个没有 ES 但可能是主写入数据库的系统,则该命令可能会由于某些数据库约束而失败。有时,将补偿作为黄金法则似乎是矫枉过正。保持简单:)
    • 也作为旁注。 Udi Dahan 在他的 Clarified-CQRS (udidahan.com/2009/12/09/clarified-cqrs) 中说:“服务器仍会验证所有到达的命令,而不是信任客户端进行验证”。但也许这仅适用于您拥有写入大师的 CQRS?
    【解决方案2】:

    在经典事件溯源模型中,获取所有客户等查询将由单独的查询处理程序执行,该处理程序侦听域中的所有事件并构建查询模型以满足相关问题。

    如果您需要按姓氏查询客户,例如,您可以监听所有客户创建和客户姓名更改事件,只需将一个姓氏表更新为客户 ID 对。您可以保存与显示数据的 UI 相关的其他信息,或者您可以简单地保存 ID 并转到相关客户的存储库,以便进一步与他们合作。

    【讨论】:

    • 客户列表与 UI 无关。想象一下,它是关于验证“CreateCustomer”命令。该验证的一部分涉及从所有其他客户那里获取一些数据。这不是 UI - 这是一个命令处理程序。它是否查询读取数据库以获取此列表?
    • 确实可以。这就是它如何处理如上所述的基于集合的验证。您的读取模型可能只是现有用户名的内存或类似 memcached 的哈希表。该读取模型与其他读取模型的一致性取决于您。
    【解决方案3】:

    您的处理程序中不需要客户列表。每个聚合必须在其自己的事务中处理。如果您想向用户显示此列表 - 只需构建适当的视图。

    【讨论】:

    • 但我 am 只处理 1 个聚合。示例:“CreateCustomer”的处理将取决于有关所有客户的信息。例如,我需要注册这是创建的第 5 个“唐老鸭”。我是否要转到名为“Donald Duck”的客户列表的查询端?
    • 在这种情况下,您需要另一个聚合来跟踪对象的创建。客户和跟踪聚合应通过事件和传奇进行通信。
    • 嗯,这对我来说听起来并不正确,但感谢您的回答。
    【解决方案4】:

    您的命令需要包含它应该操作的聚合根的 ID。 发送命令的客户端将使用您的 readmodel 中的视图查找此 ID。此视图将填充来自您的 AR 发出的事件的数据。

    【讨论】:

    • 但是让我们假设我出于某种有趣的原因需要一个客户列表来查询。我想不出一个有意义的例子,但假设我的“CustomerCreated”处理程序需要有关有多少其他客户被称为“Donald”的信息。这些信息是否需要作为命令请求中的输入(即由 CreateCustomer 中的被调用方提供),还是可以从我的处理程序中查询客户读取端?
    • @Werner,出于兴趣,你为什么不把这个作为答案?这并不能真正回答有关命令处理程序需要获取客户列表的问题。
    • @mouters:我的错,你是对的。不过我不是故意这样做的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多