Searching for a Child across Aggregate Roots

岁酱吖の 提交于 2019-12-19 10:32:48

问题


The repository pattern suggest that you can only pull aggregate roots. But how would you retrieve a single child using only it's uniqiue identity(Child.ID) if you do not know it's parent(root)?

class Parent
{
    public int ID { get; set; }
    IEnumerable<Child> Children { get; private set; }
}

class Child
{
    public int ID { get; private set; }
    public virtual Parent Parent { get; private set; } // Navigational model
}

My application is stateless (web), for simplicity, the request only contains the ID of the child.

I am thinking three approaches:

  1. Call all the parents then ask them politely who owns this child.
  2. Have a special routine in the ParentRepository called get GetChildByID, which kinda fails the repository's abstraction.
  3. Modify the request to include the parent, but seems unnecessary since you already have a unique identity.

回答1:


It seems likely that you're actually looking at a different bounded context here. You mentioned in your question that "repository ... can only pull aggregate roots."; this is correct. Another answer also mentions that if you need to query a child object, the child object may also be an aggregate root. This may also be correct within a different bounded context. It's quite possible for an entity to be an aggregate root in one context, and a value entity in another.

Take for example the domain of Users and the mobile/tablet Apps they have installed on their devices. In the context of the user, we might want the users basic properties such as name, age etc, and we might also want a list of apps the user has installed on their device. In this context User is the aggregate root and App is a value object.

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
    }
}

In another context we may take an App centric view of the world and decide that App is the aggregate root. Say for example we wanted to report which users have installed a given app.

bounded context AppUsers
{
    aggregate root App
    {
        Id : Guid
        Name : string
        InstalledBy : User list
    }

    value object User
    {
        Id : Guid
        Name : string
        InstalledOn : Date
    }
}

Both of these bounded contexts would have their own repository which returns the respective aggregate root. There's a subtle but crucial difference in your perspective of the data.

I think if you take a step back and think about why you want to query for a child object, you might find that you're actually in an entirely separate bounded context.




回答2:


If you require the child for display/reporting/viewing/reporting then a simple query layer will do.

If you are manipulating the child in any way then it has a consistency boundary and it sounds an awful lot like an aggregate.

Try not to query your domain objects. Another simple rule of thumb is not not include an aggregate reference in another aggregate but to rather use just the referenced aggregate's Id or even a value object representing the relationship.




回答3:


Entity navigation is not a purpose of a domain model.
An Aggregate Root is a composition of Entities and Values that expose business operations.
As a side effect, you can still perform some simple query or navigation through your AR, but, for complex querying, creating and using a Query Model is more efficient.
I'm talking about CQRS.

Hope this can help you.



来源:https://stackoverflow.com/questions/20189421/searching-for-a-child-across-aggregate-roots

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!