gpt4 book ai didi

entity-framework - 域事件中的新实体 ID

转载 作者:行者123 更新时间:2023-12-04 01:04:25 25 4
gpt4 key购买 nike

我正在使用 CQRS 和域事件概念(但没有事件源,只是普通的旧 SQL)构建一个具有域模型的应用程序。 SomeChanged 类型的事件没有问题。然后我陷入了实现SomethingCreated事件的困境。

当我创建一些映射到具有身份主键的表的实体时,在实体被持久化之前我不知道 Id。实体是持久性无知的,因此当从实体内部发布事件时,Id 是未知的 - 它仅在调用 context.SaveChanges() 后神奇地设置。那么如何/在何处/何时将 Id 放入事件数据中?

我在想:

  • 包括对事件中实体的引用。这将在域内工作,但不一定在具有多个自治系统通过事件/消息进行通信的分布式环境中工作。
  • 覆盖 SaveChanges() 以某种方式更新排队等待发布的事件。但是事件是不可变的,所以这看起来很脏。
  • 摆脱身份字段并使用实体构造函数中生成的 GUID。这可能是最简单的,但可能会影响性能并使其他事情变得更难,例如调试或查询( where id = 'B85E62C3-DC56-40C0-852A-49F759AC68FB' ,没有 MINMAX 等)。这就是我在许多示例应用程序中看到的。
  • 混合方法 - 撇开身份,主要用于外键和更快的连接,但使用 GUID 作为唯一标识符,我通过它从应用程序的存储库中提取实体。
  • 最佳答案

    我个人喜欢唯一标识符的 GUID,尤其是在数字 id 会导致问题的多用户分布式环境中。因此,我从不使用数据库生成的标识列/属性,这个问题就消失了。

    简而言之,由于您正在关注 CQRS,您无疑拥有一个 CreateSomethingCommand 和相应的 CreateSomethingCommandHandler,它们实际上执行创建新实例所需的步骤,并使用存储库(通过 context.SaveChanges)持久化新对象。我将在此处而不是在域对象本身中引发SomethingCreated 事件。

    一方面,这解决了您的问题,因为命令处理程序可以等待数据库操作完成,取出标识值,更新对象,然后在事件中传递标识。但是,更重要的是,它还解决了对象何时“创建”的棘手问题?

    在构造函数中引发域事件是不好的做法,因为构造函数应该精简并且只执行初始化。另外,在您的模型中,对象在分配了 ID 之前不会真正创建。这意味着在构造函数执行后需要额外的初始化步骤。如果您有多个步骤,您是强制执行顺序(另一种反模式)还是在每个步骤中进行检查以识别它们何时全部完成(哦,臭)?希望你能看到这会如何迅速失控。

    所以,我的建议是从命令处理程序引发事件。 (注意:即使您切换到 GUID 标识符,我也会遵循这种方法,因为您永远不应该从构造函数引发事件。)

    关于entity-framework - 域事件中的新实体 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11277945/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com