25

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

4

4 回答 4

26

看看这篇博文:CQRS 架构中的基于集合的验证

它解决了这个问题。这是在 CQRS 中处理的复杂问题。CustomerEmailAddressIsNotUniqueCompensatingCommandBjarte 的建议是查询现有客户电子邮件地址的报告数据库,如果找到电子邮件地址,则向域模型发出补偿命令(例如)。然后,您可以触发适当的事件,其中可能包括UndoCustomerCreationEvent.

通读上述博客文章的评论以获取替代想法。

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

我不确定这个问题是否有一个简单的解决方案,感觉完全干净。让我知道你想出了什么!

祝你好运!

于 2010-01-06T23:05:02.003 回答
5

这个问题不必那么复杂:

  1. 在提交 UpdateCustomer 命令之前检查您的报告商店的客户唯一性。
  2. 为您的数据库添加一个约束,以确保电子邮件地址的唯一性。执行命令时,处理异常并使用回复通道向用户发送通知。(因此永远不会向报告存储触发 CustomerUpdated 事件。

将数据库用于它的好处,不要被 ORM 限制所困扰。

于 2010-05-04T11:36:28.663 回答
5

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

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

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

但是,如果您不想这样做,根据上面的陈述,我建议您将“ByEmail”方法添加到存储库并完成它 - 但是 Udi 可能会有更好的建议。

于 2010-05-28T11:52:33.980 回答
2

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

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

于 2013-09-03T03:31:30.057 回答