我正在实现一个具有域驱动设计和事件溯源的应用程序。我将所有域事件存储在 SQL Server 的 DomainEvents 表中。
我有以下聚合:
- City
+ Id
+ Enable()
+ Disable()
- Company
+ Id
+ CityId
+ Enable()
+ Disable()
- Employee
+ Id
+ CompnayId
+ Enable()
+ Disable()
每个都封装了自己的域逻辑和不变量。我将它们设计为单独的聚合体,因为一个城市可能有数千(也许更多)公司,而且公司也可能有大量员工。如果这些实体属于同一个聚合,我必须将它们一起加载,这在大多数情况下是不必要的。
调用 Enable 或 Disable 将产生域事件(例如CityEnabled
,CompanyDisabled
或EmployeeEnabled
)。这些事件包含启用或禁用实体的主键。
现在我的问题是一个新要求,如果启用/禁用某个城市,则迫使我启用/禁用所有相关公司。如果启用/禁用公司,则员工也需要这样做。
在我的事件处理程序中,例如,如果CityDisabled
发生了我需要为DisableCompanyCommand
属于该城市的每家公司执行该事件处理程序。
但是我怎么知道哪些公司会受到这种变化的影响呢?
我的想法:
查询事件存储是不可能的,因为我不能使用像'where CityId = event.CityId'这样的条件
让父母知道它的孩子 id 并将所有孩子 id 放在父母产生的每个事件中。这也是一个坏主意,因为事件创建者不应该关心以后谁会使用这些事件。因此,只有属于正在发生的事件的信息才应该在事件中。
为每家公司执行
DisableCompanyCommand
。只有匹配的公司CityId
才会改变他们的状态。即使我会异步执行此操作,它也会在每个公司的这些事件上产生巨大的开销。而且对于每家被禁用的公司,应该重复相同的程序来禁用所有用户。创建读取模型,将 ParentIds 映射到 ChildIds,并根据事件中的 parentId 加载 childIds。这听起来像是最合适的解决方案,但问题是,我如何知道在禁用现有公司的同时是否创建了新公司?
我对上述任何解决方案都不满意。基本上,问题是确定发生事件的受影响聚合。
也许你有更好的解决方案?