我开始了一个新项目(重写现有解决方案),并希望使用和探索DDD。在设计我的域模型时,很难在开始时忽略实体框架。它适用于只有小型子集或只有CRUD的小型集合。现在我处在一个点,我有一个大集合的集合,我为此疯狂。
域概述
这可能看起来很恶心,但最后可能看起来像一个非常简单的问题需要解决。它是/除了以下我想要实现的东西。我不知道并且事件无法找到任何相关的东西给我答案,如果我再次考虑持久性/性能,当我不应该在域设计期间那么多。或者我的方式无法解决。
其他信息
由于每月和每年 协议条目是从系统本身(后台作业/服务)创建的,因此用户赢得了&#39;事件关心这一点。在00:00新月/年开始时添加协议条目时可能会出现短暂且短暂的错误,因为后台作业/服务尚未完成每月<当前协议的/ em>或年度条目 - 确定无误!
旧解决方案中的协议条目有两个名为 NextMonthlyEntry 和 NextYearlyEntry (DataType:DateTime)的字段。有了这些,就可以轻松而自然地询问聚合问题,例如&#34; protocol.IsYearlyOverdue()&#34;并且它还有助于在后台作业/服务中查询所有过期&#34;过期&#34;并处理每月或每年条目。我在新解决方案中重用了这些字段。
因为协议在一个月内可以拥有数千个协议条目,而在一年中甚至更多,所以每次我都无法在聚合根中加载所有这些只要协议对这些内容没有要求(就像客户AR一样不能如果不要求客户不允许一次只有5个订单,那么一直有所有订单。
问题
如何在每个协议中加载所有条目并保持行为,例如检查是否允许将条目添加到协议(我确信它与协议相关),因为它必须更新协议的(行)版本以及添加条目时的Next(Monthly | Yearly)Entry字段,以确保一致性并了解并发问题。
当我的协议获取名为 AddedEntries 的私有字段时,该字段会填充新条目。由于条目永远不会被编辑/删除,因此只能跟踪这些条目。所以我可以添加一个或多个条目,并确保一致性和验证规则。在Domain和DDD方面对我来说似乎很好,但现在在持久性方面,如何将这些 new 条目添加到数据库中?我不能只使用集合更新协议,因为这将删除不在集合(EF)中的现有条目。如果有任何条目,是否需要存储库(ProtocolRepository.Update(协议))向依赖表添加条目?
很抱歉这个问题很长,可能不是完美的标题(不知道如何用几句话来概括)。我是DDD的新手,这个问题让我发疯,如果不是一切都完全正确我也很抱歉 - 我还在学习。提前感谢大家的时间关心和思考我的问题!
答案 0 :(得分:1)
如果你想和很多孩子一起工作,请查看Vaughn Vernon的作品,特别是他在Calendar和CalendarEntry上的工作。它在Java中,但看起来非常类似于你:
注意如何建立关系,Calendar从不拥有任何CalendarEntry,而CalendarEntry引用CalendarId。
当您处理Calendar或CalendarEntry时,应用程序服务负责加载您要处理的集合,使对象进行交互并持久化它们。这样,您可以更好地控制粒度,如果您只需要当前月份的条目子集,则无需加载完整聚合,从而提高性能和内存占用。
记住DDD就是量身定制的。
因此,在您的存储库中,您可能拥有以下方法:
与他们合作,然后保存他们。
答案 1 :(得分:1)
在进行实际实施之前,您需要考虑不变量并相应地塑造模型。
确定在添加var a = ["foo", "bar"];
var b = a.slice(); // array copy
console.log(`a is ${a}`);
console.log(`b is ${b}`);
b.splice(1, 1);
console.log(`a is ${a} (not changed)`);
console.log(`b is ${b}`);
b = a;
时强制执行不变量所需的数据,并在无处不在的语言中找到有意义的名称(是Entry
吗?)
您是否可以在没有性能问题的情况下将该内容作为Aggregate的一部分加载?
这里的问题可能是过度概括 - 将所有内容视为另一个MonthlyProtocolEntry
会阻止您考虑所有可能的设计,尤其是那些具有更专业,细粒度部分的设计。