我有一个问题,当使用D#和使用C#/ EF Core时,我不确定如何解决。 简化情况:我们有2个汇总- Item 和 Warehouse 。他们每个人都具有由ExternalId(Guid)标识的身份,以在外部(FE等)标识它,这也被视为其域标识。它还具有 database 标识,可以在数据库模型中对其进行标识-实体模型和Db模型与EF Core允许使用私有字段的类相同,仅公开ExternalId和必填字段。实体(在DDD和EF核心意义上)都包含大量与对象严格耦合的业务逻辑和方法。通常,我遵循eShop / eShopOnContainers示例中的模式。
项目已分配给仓库,并且在创建项目时,我们需要将仓库传递给其构造者。
是否将完整的Warehouse对象传递给Item的构造函数(也传递给Item定义的其他方法):
public Item(Warehouse warehouse,..)
或者仅在数据库ID上中继:
public Item(long warehouseId,..)
我对此有一个问题,因为从一方面我读到聚合不应引用其他聚合,但另一方面,使用Datbase DB会将实现细节(关系DB中的对象持久性)泄漏给域模型,而该模型不应在我看来发生。
使用ExternalId:
public Item(Guid warehouseId,..)
不能解决问题,因为db中的实际关系不基于此。
您对此有何看法?我有点困惑。
答案 0 :(得分:1)
通常,您将为聚合根的ID创建一个值对象。一种可能是依靠数据库生成的ID。如果您决定让Db生成ID,那么您将需要使用该ID。 但是,为什么您仍然需要传递仓库参考或ID?看起来Item是一个实体,Warehouse是应该包含该实体的聚合根。通常,您不应在“聚合根”之外创建实体。
编辑:正如Vaughn Vernon在红皮书中描述的那样,有几种身份创建策略。其中之一是让持久性机制(例如SQL Db)生成实体或集合的唯一标识符。
答案 1 :(得分:0)
您在分析期间创建的域模型通常与设计期间创建的域模型不同。从语义上讲,它们都是相同的,您正在传递引用,但是设计模型认识到您必须持久存储数据,因此出于性能原因,您可能不想预加载所有引用的对象,无论是简单地从磁盘中的磁盘中加载它。同一域,或来自另一个域中的远程服务。