DDD声明您应该只通过其聚合根访问实体。 例如,假设你有一个聚合根X,它可能有很多子Y实体。 现在,对于某些情况,您一次只关心这些Y实体的子集(可能您正在将它们显示在分页列表中或其他任何内容中)。

那么实现存储库是否可以,以便在这种情况下它返回一个不完整的聚合? IE浏览器。 一个X对象谁只有Ys集合只包含我们感兴趣的Y实例而不是所有它们? 例如,这可能导致X上的方法执行一些涉及Ys的计算不能按预期运行。

这或许表明有问题的Y实体应被视为提升为聚合根吗?

我目前的想法(在C#中)是利用LINQ的延迟执行,以便我的X对象具有IQueryable来表示它与Y的关系。这样,我可以通过过滤实现透明的延迟加载...但是让它工作使用ORM(在我的情况下Linq到Sql)可能有点棘手。

还有其他聪明的想法吗?

===============>>#1 票数:6

我认为具有很多子实体的聚合根是代码气味,或者如果你愿意的话,会有DDD气味。 :-)一般来说,我看两个选项。

  1. 将您的聚合拆分为许多较小的聚合。 这意味着我的原始设计不是最优的,我需要识别一些新的实体。
  2. 将您的域拆分为多个有界上下文。 这意味着有一组特定的场景使用聚合中实体的公共子集,而有其他一组场景使用不同的子集。

===============>>#2 票数:4

Jimmy Nilsson在他的书中暗示,您可以阅读其中部分内容的快照,而不是阅读完整的聚合。 但是您不应该能够将快照类中的更改保存到数据库中。

Jimmy Nilsson的书第6章:准备基础设施 - 查询。 第226页。

快照模式

===============>>#3 票数:1

你真的在问两个重叠的问题。

  1. 你的问题的标题和前半部分是哲学/理论的。 我认为仅通过“聚合根”访问实体的原因是抽象出你所描述的各种实现细节。 通过聚合根进行访问是一种通过拥有可信访问点来降低复杂性的方法。 通过遵守惯例,您可以消除摩擦/模糊/不确定性。 无论它是如何在根目录中实现的,你只要知道当你要求一个实体它就会存在。 我不认为这个视角排除了你所描述的“过滤后的存储库”。 但是为了让开发人员陷入成功的陷阱,应该不可能实例化存储库而不明确其“过滤性”; 同样,如果可以对存储库实例进行共享访问,则在调用者中进行编码时,“过滤性”应该是显式的。

  2. 问题的后半部分是关于在特定平台上的实现。 不确定为什么你提到延迟执行,我认为这与过滤问题完全正交。 使用LINQ实现过滤本身可能有点棘手。 也许不是内联Where lambdas,而是设置它们的集合并根据您需要的过滤器选择一个。

===============>>#4 票数:0

你被允许,因为代码无论如何都会被编译,但是如果你要进行纯DDD设计,你就不应该有不完整的对象实例。

如果您害怕加载一个只使用其子实体的一小部分的巨大对象,您应该查看LazyLoading。

LazyLoading延迟加载任何你决定延迟加载的内容,直到它们被访问为止。 一旦代码调用它们,它们就使用回调来调用加载方法。

===============>>#5 票数:0

那么实现存储库是否可以,以便在这种情况下它返回一个不完整的聚合?

一点也不。 Aggregate是一个改变系统状态的跨国界限。 切勿使用聚合来查询数据。 将系统拆分为写入和读取端。 (阅读关于CQR和CQRS)。 当我们认为“CRUD”为基础时,我们基于一些资源实现我们的系统。 假设您有“预约”汇总。 思考“Crudish”意味着我们应该实现用例创建,更新,删除,GetAll约会。 这意味着应该为GetAll返回Appointment []。 当您认为基于usecase时,(HexagonalArchitecture)您的用例将是ScheduleAppointment,RescheduleAppointment,CancelAppointment。 但对于查询方面,它可以是:/ myCalendar。 我们返回ClientCalendar对象中特定用户的所有约会。 为查询方创建单独的DTO。 切勿将聚合物用于此目的。

  ask by Fredrik Kalseth translate from so

未解决问题?本站智能推荐:

5回复

.NET中的DDD /聚合

我一直在阅读Evans关于DDD的书,并且正在考虑如何在.NET中实现聚合。 目前,我只能想出一个方法; 在单独的类库中隔离聚合。 然而,这看起来有点过分(我宁愿将所有域对象保留在一个库中),我想知道是否有不同的方法? 1 lib / aggregate的原因如下:聚合根需要知道它负
2回复

DDD中的聚合对象

我创建了一个名为Question的聚合类。 这包含对Answer , Category , Feedback对象的引用。 QuestionRepository应该是包含查询与问题相关的数据库的所有方法的类,还包括查询反馈,答案等的所有方法? 或者它们应该是单独的类,例如QuestionRe
1回复

聚合和DDD

我正在开发一个使用DDD原理的项目,我创建了一个类聚合(帐户),它将包含类(代理)和(代理),这两个类((帐户)在数据库中都有表)。 我的问题是这样的: 我需要为我的每个实体(帐户,代理和代理)创建一个存储库类和一个服务类,还是应该创建一个AccountRepository并在其中进行3
1回复

处理DDD中的嵌套聚合

我刚开始使用DDD,但在弄清楚如何适应数据的关系性质时遇到了一些麻烦。 我有被认为是我的聚合根的人,但是聚合也有自己的聚合。 不想违反Demeter法则,我想知道我是否正在考虑这一错误,并希望DDD专家可以提供一些见解。 我的聚合根是我的Account对象,该对象具有许多Account
1回复

聚合DDD中的根实体

我试图了解域驱动设计中的聚合根。 聚合根是否可以具有深层嵌套的实体? 像一个实体中的一个实体,还是总根应该具有浅薄的实体集合? 谢谢,拉维
1回复

在DDD中聚合根和存储库

我刚开始使用DDD并遇到术语聚合根。 我目前的理解是,这是一种包含其他互补实体的父实体。 示例:聚合根将是员工,其中还包含职位,班次,性别,工资。 我的第一个问题是这种理解是否正确? 其次,我得到的印象是只为每个聚合定义了存储库。 然而,我们如何能够检索有关其他实体的信息(例如
2回复

DDD和实体框架中的聚合

我有一个问题,关于如何处理不是数据库中数据表示的实体,而是我为业务目的需要的定制实体。 我的解决方案结构如下: 实体装配(POCO对象) 存储库程序集(EF代码优先) 业务层组装 UI程序集(MVC) 在我的实体程序集中,我有两个实体, A和B ,
2回复

聚合DDD中的对象,这是潜在的聚合吗?

我有两个实体Question和QuestionLog。 问题显然代表一个问题,QuestionLog代表用户可以针对特定问题报告的实体。 例如,如果问题是错误的,质量不佳等。 现在,从我已阅读的内容中,聚合对象是唯一具有存储库的对象,并且,如果移除了附加到数据库中的问题,那么Quest
1回复

DDD中的根和聚合根有什么区别

我的朋友在一次采访中遇到了这个问题,我们仍然找不到答案。 DDD中的根和聚合根有什么区别? 我们知道DDD中存在聚合根,但不知道根概念,所以这是一个有效的问题吗?如果是,那么有什么区别?
1回复

使聚合在DDD中可分页[关闭]

我有一个集合可以通过Controller,Service和Repository层传递。 根据DDD,总体上没有有关雄辩模型的相关信息。 我需要对该存储库返回有关该聚合的聚合进行分页。 是更适合为其创建另一个对象,还是可以将有关分页的信息放入DDD中的聚合中?