nhibernate - 使用 NHibernate 进行事件溯源

标签 nhibernate domain-driven-design cqrs event-sourcing

我正在从纯粹的 DDD 范式转向 CQRS。我目前关注的是事件溯源,更具体地说,是组织事件存储。我读过很多博客文章,但仍然无法理解一些东西。所以如果我错了请纠正我。

每个事件基本上包括: - 事件日期/时间 - Event 的类型(我们也可以从中找出 AggregateRoot 的类型) - 聚合根 ID(Guid) - AggregateRoot版本(维护更新顺序) - 事件数据(一些序列化类,其中包含更新所需的数据)

现在,如果我的事件数据由简单的值类型(整数、字符串、枚举等)组成,那么这很容易。但是如果我必须传递另一个 AggregateRoot 怎么办?我无法将整个 AR 序列化为事件数据的一部分(考虑所有数据和延迟加载),基本上我只需要存储该 AR 的 Id 。但是,当我需要应用该事件时,我需要首先从数据库获取该 AR。从我的域模型(调用存储库并使用 AR Id)中这样做感觉不对。

最好的方法是什么?

附:举一个具体的例子,我们假设有一个由任务和用户实体(均为 AR)组成的模型。任务保留对负责的用户的引用。但负责的用户可以更改。

更新:我想我已经找到了困惑的根源。我认为事件溯源应该仅用于构建读取模型。在这种情况下,传递 ID 和原始数据就可以了。但同样的事件也用在聚合本身上。这是我无法理解的。

最佳答案

在 DDD 中,聚合是一致性/不变性边界,因此一个人可能永远不会依赖另一个人来维持其不变性。当我们开始使用这个设计限制时,我们发现很少有需要存储对另一个的完整引用的情况,通常我们存储它的 id 和(如果需要)版本以及相关属性的副本。

例如,使用通常的订单/订单项和产品问题,我们将在订单项中复制产品的 ID 和价格,而不是完整的引用。这种方式可以防止产品价格的变化影响订单/订单项聚合的不变量。如果在产品价格更改后有必要更新 LineItem 价格,我们需要跟踪已使用产品的 PriceChanged 事件并向订单/LineItem 发送补偿命令。通常这种协调/同步是由传奇来处理的。

关于nhibernate - 使用 NHibernate 进行事件溯源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6621803/

相关文章:

clojure - clojure 中的存储库模式

c# - 域驱动设计中上下文之间的通信

c# - NHibernate 异常 "Session is closed! Object name: ' ISession'。”

c# - Fluent NHibernate 或 NHibernate for Linq?

.net - 尝试使用它作为成员的类型来映射实体

nhibernate - Fluent NHibernate 以智能方式映射 IDictionary<string, class>

domain-driven-design - 多个域对象和存储库来支持同一实体的不同用途?

validation - DDD - 唯一约束的验证

java - Cqrs+微服务架构: how to get data from another service

naming-conventions - CQRS命名约定