C# 在聚合根中搜索子级
存储库模式建议您只能提取聚合根。但是,如果您不知道单个子项的父项(根),那么如何仅使用它的uniqiue标识(child.ID)检索它呢C# 在聚合根中搜索子级,c#,domain-driven-design,repository-pattern,ddd-repositories,aggregateroot,C#,Domain Driven Design,Repository Pattern,Ddd Repositories,Aggregateroot,存储库模式建议您只能提取聚合根。但是,如果您不知道单个子项的父项(根),那么如何仅使用它的uniqiue标识(child.ID)检索它呢 类父类 { 公共int ID{get;set;} IEnumerable子项{get;private set;} } 班童 { public int ID{get;private set;} 公共虚拟父级{get;private set;}//导航模型 } 我的应用程序是无状态的(web),为了简单起见,请求只包含子对象的ID 我认为有三种方法: 打电话给所
类父类
{
公共int ID{get;set;}
IEnumerable子项{get;private set;}
}
班童
{
public int ID{get;private set;}
公共虚拟父级{get;private set;}//导航模型
}
我的应用程序是无状态的(web),为了简单起见,请求只包含子对象的ID
我认为有三种方法:
如果需要子级进行显示/报告/查看/报告,则可以使用简单的查询层 如果您以任何方式操纵子对象,那么它有一个一致性边界,听起来非常像一个聚合
尽量不要查询域对象。另一个简单的经验法则不是在另一个聚合中包含聚合引用,而是只使用被引用聚合的Id,甚至是表示关系的值对象 实体导航不是域模型的目的。
聚合根是公开业务操作的实体和值的组合。
副作用是,您仍然可以通过AR执行一些简单的查询或导航,但是对于复杂的查询,创建和使用查询模型更有效。
我是说
希望这能对您有所帮助。看起来您实际上看到的是一个不同的有界上下文。您在问题中提到“存储库…只能提取聚合根。”;这是正确的。另一个答案还提到,如果需要查询子对象,子对象也可能是聚合根。在不同的有界上下文中,这也可能是正确的。实体很可能在一个上下文中是聚合根,在另一个上下文中是值实体 以
用户的域
和他们在设备上安装的移动/平板电脑应用程序
为例。在用户上下文中,我们可能需要用户的基本属性,如姓名、年龄等,还可能需要用户在其设备上安装的应用程序列表。在此上下文中,User
是聚合根,App
是值对象
bounded context UserApps
{
aggregate root User
{
Id : Guid
Name : string
Age : int
InstalledApps : App list
}
value object App
{
Id : Guid
Name : string
Publisher : string
Category : enum
}
}
在另一种情况下,我们可以采用以App
为中心的世界观,并确定App
是聚合根。例如,我们想报告哪些用户安装了给定的应用程序
bounded context AppUsers
{
aggregate root App
{
Id : Guid
Name : string
InstalledBy : User list
}
value object User
{
Id : Guid
Name : string
InstalledOn : Date
}
}
这两个有界上下文都有自己的存储库,该存储库返回各自的聚合根。在您对数据的看法上存在着微妙但至关重要的差异
我认为,如果您后退一步,思考一下为什么要查询子对象,您可能会发现您实际上处于一个完全独立的有界上下文中。创建一个
GetChildByID(…)ChildRepository
类中的
方法?如果您可以在没有父项的情况下识别子项,那么子项应该是聚合项。@Hippoom我对聚合根的了解是有限的,您是说只要实体具有唯一标识,那么它们就可以被视为根吗?我已经更新了代码示例。如果域专家希望单独跟踪,则实体应该是聚合的。例如,假设域专家在没有订单的情况下不会跟踪订单行,那么订单是一个聚合,而订单行只是一个本地实体。即使从技术上讲,我们也会给orderLine一个唯一的id。@Hippoom+1我想你已经一针见血了。这可能是因为此子对象在一个有界上下文中是聚合根,而在另一个上下文中是值对象。非常抱歉,感谢您的回复太晚。我会接受这个最接近我需要的答案。我现在了解到聚合根根据上下文而变化。我还发现了一篇很好的文章,它进一步帮助我理解了这件事。
bounded context AppUsers
{
aggregate root App
{
Id : Guid
Name : string
InstalledBy : User list
}
value object User
{
Id : Guid
Name : string
InstalledOn : Date
}
}