CQRS中的域查询

时间:2010-01-06 19:06:34

标签: domain-driven-design cqrs

我们正在尝试CQRS。我们有一个验证情况,其中CustomerService(域服务)需要知道客户是否存在。客户的电子邮件地址是唯一的。我们的客户存储库(通用存储库)仅具有Get(id)和Add(customer)。 CustomerService应该如何确定客户是否存在?

4 个答案:

答案 0 :(得分:24)

看一下这篇博文:Set based validation in the CQRS Architecture

它解决了这个问题。在CQRS中处理这是一个复杂的问题。 Bjarte建议的是查询报告数据库中的现有客户电子邮件地址,并在找到电子邮件地址时将补偿命令(例如CustomerEmailAddressIsNotUniqueCompensatingCommand)发回域模型。然后,您可以触发相应的事件,其中可能包含UndoCustomerCreationEvent

阅读上述博文中的评论,了解其他想法。

Adam D.在评论中建议验证是一个域名问题。因此,您可以将ReservedEmailAddresses存储在一个便于客户创建的服务中,并通过事件存储中的事件进行补充。

我不确定是否能够轻松解决这个问题,感觉非常干净。让我知道你提出了什么!

祝你好运!

答案 1 :(得分:5)

这个问题不一定非常复杂:

  1. 在提交UpdateCustomer命令之前,请检查您的报表存储区以获取客户唯一性。
  2. 向您的数据库添加约束,以确定电子邮件地址的唯一性。执行命令时,处理异常并使用回复通道向用户发送通知。 (因此永远不会向报告商店发送CustomerUpdated事件。
  3. 使用数据库获取它的好处,并且不要对ORM限制感到困惑。

答案 2 :(得分:5)

Udi Dahan http://www.udidahan.com/2009/12/09/clarified-cqrs/的这篇文章包含以下段落:

“此外,我们不需要访问查询存储来处理命令 - 任何需要的状态都应由自治组件管理 - 这是自治意义的一部分。” < / p>

我相信Udi建议简单地向数据库添加一个唯一约束。

但如果您不想这样做,基于上述声明,我建议只将“ByEmail”方法添加到存储库并完成它 - 但是再次Udi可能会有更好的建议。

答案 3 :(得分:2)

希望我不会太迟......但是我们在项目中遇到了类似的情况,我们实际上拦截了命令执行器并将其附加为为该命令创建的规则集,后者又使用查询来获取数据

因此,在这种情况下,我们可以通过名称CustomerEmailMustBeUniqueRule创建一个类,当RegisterCustomerCommandExecutor即将执行命令“RegisterCustomerCommand”时,该名称由RuleEngine获取。此规则类有责任查询数据库以查找电子邮件ID是否存在,并通过引发无效标志来停止执行...