【问题标题】:Copy entire entity using EntityId in CQRS with eventSourcing使用带有 eventSourcing 的 CQRS 中的 EntityId 复制整个实体
【发布时间】:2015-09-09 12:30:56
【问题描述】:

我正在使用带有事件溯源的 CQRS。我有一个实体,例如带有 entityId 的表单。现在我必须在这个实体上发送复制命令(CommandName:CopyForm,EventName:FormCopied)所以,应该复制整个表单并具有不同的entityId。

因此,为了实现这一点,我使用 CopyForm 命令发送表单的 entityId,该命令需要被复制。整个表单是从事件存储加载的,在引发事件时,我将事件引发为 FormAdded 而不是 FormCopied ,它将添加与我们从 eventStore 加载的源表单完全相同的新表单,并且只是设置新的 entityId 。但是这里的问题是为我正在复制的相同表单而不是复制表单引发事件。我的框架不允许更改 entityId。框架默认设置我为源表单提出的命令的 entityId,并且为具有相同 entityId 的源表单引发事件。

有没有更好的方法在 CQRS 中使用 Event-Sourcing 为实体执行复制功能?

【问题讨论】:

    标签: c# cqrs event-sourcing


    【解决方案1】:

    发布声明新事实的事件:

    FormCopied { OriginalEntityId, NewEntityId }
    

    结合域的历史,您现在有足够的信息来准确了解副本应包含的内容,以及两个实体的关系(带有 id)。

    【讨论】:

    • 原始实体的版本也要包括在内:o)
    • @SirRufo:FormCopied 事件告诉我们原件被复制的时间点,在不引入额外数据的情况下为我们提供了足够的信息。事件溯源非常棒,因为您可以利用时间关系,而这在 n 层系统中通常会丢失。
    【解决方案2】:

    Bryan 的回答很好,但有点不完整。

    在事件溯源系统中,域的命令服务需要能够从事件日志中恢复实体。无论事件日志的后备存储是什么,它都可能由 EntityID 索引,并且实体将通过从后备数据存储中提取给定 EntityID 的所有事件来重新水化。因此,FormCopied 事件需要有一个标准的 EntityId 字段,不是吗?

    我们可以使用以下内容:

    FormCopied { EntityId, OriginalEntityId }
    

    这与 Bryan 的回答略有不同,因为它允许使用 EntityId 索引的事件存储。

    FormCopied 事件将成为重新水合新“表单”实体的流的一部分似乎是正确的。但仍然存在问题。例如,假设接下来我们的用户尝试向他/她的表单添加一个新字段。下面是一个可能的下一个命令:

    AddFieldToForm { EntityId, NewField }
    

    现在,想象一下这个“表单”实体有一些业务规则需要检查,就像实体经常做的那样。命令服务将要加载新的“表单”实体以检查业务规则,因此它将尝试从事件日志中重新水化“表单”实体。我们拉出事件日志,只找到一个事件。

    FormCopied { EntityId, OriginalEntityId }
    

    因此,现在我们必须返回事件日志并拉取 OriginalEntityId 的事件流,以便获得新实体的完全水化副本。至少有两种方法可以做到这一点:

    1. 通过实际提取 OriginalEntityId 的事件流,然后重放它,就好像它的事件源自这个新实体 - 或 -
    2. 通过加载与 OriginalEntityId 对应的原始实体并将其属性一一复制到新实体。

    您选择哪一种取决于您的框架的功能。

    【讨论】:

    • 如果我们将事件提升为 FormAdded 而不是 FormCopied 怎么办?为什么我们仍然不需要单独引发之前为原始实体发生的每个事件?
    【解决方案3】:

    您的情况似乎有点奇怪,但无论如何,我能想到的最简单的方法是获取表单的事件流,复制它们并替换副本中的实体 ID(您可以这样做,因为事件是简单的数据结构)。然后保存并发布新的事件流。如果复制的事实具有域意义,则 FormAdded 事件可以具有属性IsCopied

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-19
      • 2017-03-18
      • 1970-01-01
      相关资源
      最近更新 更多