Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在聚合根中搜索子级_C#_Domain Driven Design_Repository Pattern_Ddd Repositories_Aggregateroot - Fatal编程技术网

C# 在聚合根中搜索子级

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 我认为有三种方法: 打电话给所

存储库模式建议您只能提取聚合根。但是,如果您不知道单个子项的父项(根),那么如何仅使用它的uniqiue标识(child.ID)检索它呢

类父类
{
公共int ID{get;set;}
IEnumerable子项{get;private set;}
}
班童
{
public int ID{get;private set;}
公共虚拟父级{get;private set;}//导航模型
}
我的应用程序是无状态的(web),为了简单起见,请求只包含子对象的ID

我认为有三种方法:

  • 打电话给所有的父母,然后礼貌地问他们这个孩子的主人是谁
  • 在ParentRepository中有一个名为get GetChildByID的特殊例程,它使存储库的抽象失败
  • 修改请求以包含父项,但似乎没有必要,因为您已经具有唯一标识

  • 如果需要子级进行显示/报告/查看/报告,则可以使用简单的查询层

    如果您以任何方式操纵子对象,那么它有一个一致性边界,听起来非常像一个聚合


    尽量不要查询域对象。另一个简单的经验法则不是在另一个聚合中包含聚合引用,而是只使用被引用聚合的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
        }
    }