Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 事件源-显示旧数据_Database_Cqrs_Event Sourcing - Fatal编程技术网

Database 事件源-显示旧数据

Database 事件源-显示旧数据,database,cqrs,event-sourcing,Database,Cqrs,Event Sourcing,这是一个noob(我认为)活动 问题 例如,我们有: 鞋匠鲍勃 顾客爱丽丝 鞋匠鲍勃: “鞋匠商业地点”(商业地点地址) 第一个地址是“贝克街88d8-5号”(于1月添加) 第二个地址是“73c6-6卡德曼广场”(于3月添加) 在某个特定点(10月)鞋匠从 “贝克街5号”到“贝克街11号”(街区下的几栋房子) 假设我们有一个“鞋子维修订单”(聚合根?) 我们收到了爱丽丝的修鞋订单 7月的某个时候,鞋匠鲍勃搬家之前 他在街区那头的生意地点 假设Alice正在查看12月份的订单。 显然

这是一个noob(我认为)活动 问题

例如,我们有:

  • 鞋匠鲍勃
  • 顾客爱丽丝
鞋匠鲍勃:

  • “鞋匠商业地点”(商业地点地址)
    • 第一个地址是“贝克街88d8-5号”(于1月添加)
    • 第二个地址是“73c6-6卡德曼广场”(于3月添加)
    • 在某个特定点(10月)鞋匠从 “贝克街5号”到“贝克街11号”(街区下的几栋房子)
假设我们有一个“鞋子维修订单”(聚合根?)

  • 我们收到了爱丽丝的修鞋订单 7月的某个时候,鞋匠鲍勃搬家之前 他在街区那头的生意地点

  • 假设Alice正在查看12月份的订单。 显然,她不必知道鲍勃搬家了。 当她看到她的订单时,我认为她应该(至少)看到旧订单 营业地点和/或 “在贝克街5号订购(新地址为贝克街11号-10月6日更新)”

问题:我们如何设计事件源系统来显示订单的旧地址

  • 我们是否必须始终为订单存储事件,例如 “OrderLocationAdded”并将实际地址的副本与我们的订单事件一起存储- 这样,每个订单都会有一个正确的旧位置,只需从事件中获取。 只有通过发出诸如“OrderLocationUpdated”之类的新事件,我们才能更新它 如果需要的话,可以订购

  • 我们是否发出一个引用地址的“OrderLocationAdded”事件 “88d8在版本1”,以便我们知道如何查找我们业务位置的版本1。 我们将不得不重播“鞋匠商业地点”上的事件 直到我们看到地址的“版本X”(在我们的例子中是版本1)。 这就是我们必须对所有旧订单所做的,这些旧订单的 地址低于当前设置的版本(版本1)

  • 还有别的办法吗

    也许我们的读取模型只是在不同的版本中存储了所有的地址信息,当查询某个版本时,我们可以 不必在我们的写模型中重播事件,只需从我们的读模型中获取版本1中的地址


我认为实现这一点的最佳方式最终取决于您如何设计域模型,但以下是我将如何解决这个问题:

我们需要在域模型中表示地址。这意味着,地址将是值对象、实体或聚合。其中,地址实际上只能是这个域中的值对象或实体,因为我们是一个修鞋应用程序,而不是地址簿。实体具有某些属性,如通过其ID进行区分,以及某些限制,如仅作为一个聚合的一部分,而地址似乎不满足这些限制。因此,我会看到一个地址是这个域中的一个值对象

在“shoe_repair_order”聚合上定义OrderLocationAdded事件时,您需要决定是在事件中包含地址的完整详细信息,还是使用对地址的引用。因为地址是一个值对象(它是由它的数据定义的,而不是由ID定义的),所以答案是在事件中包含值对象。这样,当您重播事件以构建订单的当前状态时,它仍将具有原始地址的详细信息


如果还希望在订单上显示新地址,可以使用另一个事件(如BusinessMovedToNewLocation)显示新地址的详细信息,并将其添加到订单中。此事件不会替换原始地址,它只允许您显示信息消息,说明该企业现在位于不同的位置。

由于CQR的存在,答案非常简单:您不能收听
OrderDetailsReadModel
中的
BusinessMovedToANewLocationEvent
。当发生
OrderPlacedEvent
时,您只需在此
Read model
中的
Order details
中查找并存储一次当前的
Business address

这样,您就不必在事件中包含任何
地址值对象。
读取模型
完成所有工作


如果出于其他原因需要,您可以收听该活动,但不要更新地址。例如,
读取模式可以更加智能,并在同时保持
地址更改
布尔值
标志,以便告诉
Alice
她看到的
地址是一个旧地址,但这取决于您的业务需要。

您的问题的答案当然取决于您的工作方式定义域模型(特别是如何定义聚合)。解决此问题的方法是使用两个聚合:

  • 鞋匠骨料(在您的案例中,它存储了所有信息,如鞋匠企业的名称、有关该企业所有者的信息、该鞋匠的所有地址列表,其中每个地址都可以包含电子邮件、电话号码和一个名为current的布尔字段,该字段对当前地址而言可能是真的。我想象这个AR会有一个名为-“ChangesOemakerCurrentAddress”,它将引发一个名为“ShoemakerAddressChanged”的事件

  • 订单聚合(包含订单的所有信息,如客户名称、价格、详细信息、订单日期、交货日期等)

假设我们有一个名为“ShoeMakerOrderReadModel”的读取模型,它可以订阅由ShoeMaker聚合和Order聚合引发的事件。该读取模型侦听事件并将其反规范化为POJO/POCO对象。