我希望了解人们可能采取了哪些方法来检测作为其聚合的一部分的实体中的更改。我有一些有用的东西,但我并不为此感到疯狂。基本上,我的存储库负责确定聚合根的状态是否已更改。假设我在聚合中有一个名为 Book 的聚合根和一个名为 Page 的实体。 Book 包含一个或多个 Page 实体,存储在 Pages 集合中。

首先,插入与更新方案是通过检查聚合根及其实体来确定密钥的存在来完成的。如果存在密钥,则假定该对象一次被保存到基础数据源。这使它成为更新的候选者;但对于实体而言,它并不是唯一的基础。对于聚合根,答案是显而易见的,因为只有一个并且它是奇异的入口点,可以假设密钥存在将决定操作。在我的情况下,可以接受的方案是再次保存聚合根本身,以便我可以捕获修改日期。

为了帮助促进实体本身的这种行为,我的 EntityBase 类包含两个简单的属性: IsUpdated() IsDeleted()。这两个都默认为false。我不需要知道它是否是新的,因为我可以根据密钥的存在做出决定,如前所述。实现方法(在本例中为Page)将使每个方法将后备数据集 IsUpdated()更改为true。

因此,例如,Page有一个名为 UpdateSectionName()的方法,它改变了 SectionName 属性的后备值,该属性是只读的。这种方法被一致地使用,因为它允许执行该数据设置的方法中的验证器的逻辑连接点(防止实体进入无效状态)。最终结果是我必须在方法结尾处放置 this.IsUpdated()= true;

当聚合根被发送到 Save()的存储库时(逻辑切换到 Insert() Update()操作),然后它可以遍历 Book 中的 Pages 集合,查找具有三种情况之一的任何页面:

  1. 没有钥匙。将插入没有密钥的 Page
  2. IsDeleted = true; 删除优先于更新,删除将被提交 - 忽略 Page 的任何更新。
  3. IsUpdated = true; 将为该页面提交更新。
  4. 这样做可以防止我盲目地更新Pages集合中的所有内容,例如,如果Book中有几百个Page实体,这可能会让人望而生畏。我一直在考虑检索本书的副本,并进行比较并仅提交检测到的更改(基于存在和/或比较的插入,更新和删除),但它似乎是一种非常繁琐的方式来实现它

    主要缺点是开发人员必须记住在实体中的每个方法中设置IsUpdated。忘记一个,它将无法检测到该值的更改。我已经玩弄了某种自定义后备存储的想法,该存储可以透明地为更改添加时间戳,这反过来可以使 IsUpdated 成为存储库可用于聚合更新的只读属性。

    存储库使用工作模式实现单元,该工作模式实现基于将聚合根添加到其中时生成的时间戳。由于可能有多个实体queu

有帮助吗?

解决方案

简而言之,我的回答是我选择了我的建议。它确实有效,但我确信还有改进的余地。这些变化实际上花了很少的时间,所以我觉得在这种情况下我没有离开KISS或YAGNI校长太远。 : - )

我仍然觉得在操作方面存在计时相关问题的空间,但我应该能够在存储库实现中解决这些问题。不是理想的解决方案,但我不确定是否值得重新发明轮子以纠正可以在更短的时间内避免的问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top