我正在尝试在事件存储中构建关系。我是事件采购的新手,所以请耐心等待。:-)
如何在事件存储中映射关系?你能给我一些建议吗?
想象一下,我有一个关于项目管理的领域。我有一个聚合,它是一个Project
。Project
聚合根包含Tasks
、Documents
、Files
、Folders
,它们是Project
中核心实体的集合。 我还有一个ProjectBranch
,它可以是Project
聚合的一部分,但也可以独立查看。在ProjectBranch
中,可以更改前面提到的集合,并且可以再次将ProjectBranch
合并到Project
中,从而更新Project
的集合。
某些流程类似于 VCS 系统。
应如何映射这些关系,以及应创建聚合根和聚合根的哪种分离?
如果Project
是唯一的聚合,则事件(我想(如下所示:
- ProjectWasCreated [聚合]
- 项目文档已创建
- ProjectTaskWasCreated(项目任务(
- 项目分支已创建
- ProjectBranchDocumentWasCreated(
这个事件将如何知道文档属于哪个分支(
一旦 ProjectBranchWasMergedToProject 事件发生,ProjectBranch
中发生的所有事件都必须以某种方式在项目上重播。
另一方面,可能存在一个更关系的结构,其中有几个单独的聚合 - 例如Project
、ProjectBranch
、Task
、Document
等。
这意味着域具有一组不同的事件,可能如下所示:
- ProjectWasCreated [聚合]
- 文档已创建 [聚合]
- ProjectDocumentWasAttached(documentId(
- ProjectBranchWasCreated(projectId( [aggregate]
- 文档已创建 [聚合]
- ProjectBranchDocumentWasAttached(documentId(
其中一些功能可能需要在Project
之外独立工作,因此它们将被制作为独立的模块。
谢谢 :-(
假设所有这些元素都是聚合的:Project
、ProjectBranch
、Task
、Document
等等。
构造聚合的基本原则之一是它们形成事务一致性边界,这意味着在单个聚合中,所有元素必须保持一致,并在事务发生时满足关联的业务规则。
这就是为什么人们通常坚持使用小的聚合结构,大多数聚合中只有一个实体。随着Project
的增长,您将不可能使所有这些元素保持同步和一致。
现在进入你的问题,关系的答案分为两部分:
-
聚合之间的所有链接都应采用聚合标识的形式。如果
Task
链接到Project
,则Task
聚合事件将包含ProjectId
作为属性。不应将聚合结构存储在彼此内部。
如果您使用的是RDBMS,则聚合之间所需的任何同步(例如,如果项目已关闭(都应在域事件的帮助下完成。
但是,由于您使用的是事件溯源,因此无需在后台执行此操作。你动态地构建聚合结构,这就把我们带到了第二点。
-
与任何其他 EventSource 投影一样,在构造聚合对象时,需要重新构造内部数据元素。
如果希望项目结构可用作任务投影的一部分,请调用项目应用程序服务以实时检索项目聚合。
对于您可能希望作为投影的一部分的所有链接聚合,依此类推。