事件溯源、CQRS、DDD:一对多关系

Event Sourcing, CQRS, DDD: One-to-Many relationship

我是 CQRS 事件溯源的新手。我正在尝试定义我的程序的聚合根。 假设我有这两个实体:汽车和人。还有一个不变量:一辆车只能由一个人拥有。

它基本上是Person和Car之间的1-TO-M关联

我有这三个命令:

  1. 重绘汽车(只给出汽车id)

  2. 更改车主(给定车号和新人号)

  3. 重新粉刷一个人拥有的所有汽车(只给出个人 ID)

如果我将汽车用作 AR,命令 #1 会很快 运行。我将推送一个 CarRepaint 事件。命令 #2 也很快 运行(推送 CarIsOwnedBy 事件) 但是命令 #3 出现了问题,我需要遍历商店中的所有事件以获取特定人员拥有的每辆汽车。不变量也很容易实现。

如果我使用 Person 作为 AR,命令 #3 会很快 运行。我将为与此人关联的每辆汽车推送 CarRepaint 事件。 但是命令 #1、#2 出现问题,我需要去查看商店中的所有事件以找到好车。我在确保不变量保持为真时也遇到了问题。

我是不是以错误的方式解决了这个问题?

感谢您的帮助

你没有提到的几个选项可以让你解决这个问题,而不会限制你只能选择一个或另一个作为聚合根。

  1. 一个小型的写入端读取模型订阅相关事件,并随时了解什么人拥有什么汽车。当 "repaint all Cars owned by a Person" 命令被接受时,命令处理器使用这个小模型提供汽车 ID。
  2. A "repaint all Cars owned by a Person" 命令提交汽车 ID,该 ID 是预先从读取的模型中检索到的。 (这可能不适合您的域,但在某些情况下这是正确的安排,因为它允许提交命令的代理在提交之前检查列表。)

Am I approching the problem in the wrong way?

没有。您可能还没有完成,但到目前为止的方法是合理的。

首先要检查的是这个模型是否是汽车的权威,或者它是否只是记录来自其他权威(比如现实世界)的数据。如果现实世界是权威,那么你需要在事件中思考,而不是命令;领域模型不应该试图否决来自现实世界的证据。

但假设目前模型是权威,接下来要看的是你的失败模式(根据我的经验,关注快乐路径告诉你很少关于如何组织你的模型)。如果四辆车中有一辆拒绝喷漆,会发生什么情况?你不画它们吗?你再把它们拆掉吗?你让他们一个人呆着吗?

你可能要考虑的另一件事是 "all cars" 的模糊性是否是模型应该支持的东西。如果模型是汽车集合的记录簿,则模型可以在命令执行期间更改该集合。所以也许 all cars 不是正确的拼写。所有汽车 截至特定时刻 是不可变的,但可能仍然模糊。此提供的列表中的所有汽车都是明确的。

您还应该考虑您是在描述一个命令(一个全有或全无事务)还是一个进程(协调多个命令)。可能是操作员刚刚开始对汽车进行喷漆的过程,模型进行编排,向集合中的每辆汽车发送适当的命令。