获取所有聚合根实体子实体?

时间:2011-09-18 10:42:12

标签: asp.net-mvc-3 domain-driven-design ddd-repositories service-layer aggregateroot

我正在尝试将我的应用程序从每个实体的存储库重构为每个聚合根的存储库。

一个基本的例子是我有一个Cars的实体根。汽车有租赁合同。据我所知,没有汽车就不存在合同,因此汽车是合计的根。

我正在尝试实现一个用户视图,它将显示系统中的每个合同(根实体的所有子实体)。在重构之前,我可以去我的合同存储库并获取All。由于合同存储库已被删除(因为它不是根)我现在需要将所有汽车从我的存储库中取出然后获得所有合同。

我的存储库有界面

public interface ICarRepository
{
    IQueryable<Car> All { get; }
    IQueryable<Car> AllIncluding(params Expression<Func<Car, object>>[] includeProperties);
    Car Find(long id);
    void InsertOrUpdate(Car car);
    void Delete(long id);
    void Save();
}

我想过创建一个ICarManagementService并让它有一个GetAllContracts方法(可能带有过滤器参数)。这是否意味着获得我需要的所有合同,将所有汽车实体与合同拉出来,然后检索每个实体相关的租赁合同并过滤它们?

然后我可以像往常一样将这些传递给控制器​​并自动映射合同。

这是最佳做法吗?

由于

格雷姆

2 个答案:

答案 0 :(得分:5)

  

据我所知,没有汽车就不存在合同,因此汽车就是   聚合根。

这不一定是真的。 '不存在'不足以使实体成为聚合根的一部分。考虑经典订单处理域。您有一个聚合根订单。您还有一个聚合根客户。没有客户,订单就不可能存在,但并不意味着订单是客户聚合的一部分。在DDD中,一个Aggregate中的实体可以引用其他聚合根。来自DDD book

  

AGGREGATE中的对象可以保存对其他AGGREGATE的引用   根。

Aggregate是一个生命周期和数据交换单元。它本质上是一个强制不变量的对象集群。如果您有多个用户同时更改域,则您希望将其锁定。

回到你的问题,我的理解是该域名就像出租/租赁汽车/卡车/豪华轿车/推土机。我认为HireContract可能不是Car聚合的一部分,因为它们可能有不同的生命周期,HireContract本身就有意义,没有Car。它似乎更像是一个Order-Product关系,它也是两个不同Aggregates相互引用的典型例子。企业需要看到“所有合同”这一事实也证实了这一理论。他们可能不会想到Car包含所有合同。如果这是真的,那么你需要保留ContractsRepository。

在不相关的说明中,您可能有兴趣阅读有关存储库界面设计的answer

答案 1 :(得分:3)

将读/查询的概念与写/命令分开,在CQRS的指导下,最好通过分离由只读查询组成的读模型和另一方面由命令组成的写模型来设计应用程序。在域模型上执行某些逻辑。

因此查询所有聚合根或创建自定义查询以加入数据集不是域存储库的良好候选者,而是将这些查询放入读取存储库(或更好的命名Finders)。

如果您发现自己想要查询对象集合以执行某些域逻辑,则表明您必须抽象此集合并将其放入聚合根中以封装它们并进行业务操作或方法对他们采取行动。

退房(http://moh-abed.com/2011/09/13/pure-old-ddd-with-a-twist-from-cqrs/)和(http:// simon-says-architecture的.com / 2011/08/23 /库)