How to avoid saving the full aggregate root when adding a child?

I have a cumulative root domain model:

public interface IAggregateRoot { public string Id { get; } public string Foo { get; set; } public int Bar { get; set; } public IList<IChildEntity> Children { get; } } 

The Kids collection has a tendency to grow very large, and I will lazily load it when an IAggregateRoot instance is retrieved through the IAggregateRootRepository. My problem is this; if I want to add IChildEntity to the IAggregateRoot Children collection, how will my repository avoid me saving the entire aggregate?

For example, let's say my IAggregateRootRepository should look like this:

 public interface IAggregateRootRepository { public IAggregateRoot GetById(string id); public void AddOrUpdate(IAggregateRoot root); } 

Then I could add to the Children collection by getting an IAggregateRoot instance through IAggregateRootRepository.GetById (), adding a child to the Children collection, and then saving it through IAggregateRootRepository.AddOrUpdate (). However, this will persist throughout the aggregate root, along with its massive collection of children, every time I add a child. I think I could get around this if my repository looked like this:

 public interface IAggregateRootRepository { public IAggregateRoot GetById(string id); public void AddOrUpdate(IAggregateRoot root); public void AddOrUpdate(IChildEntity child); } 

But, since I understood the repository template, the repository should deal only with the aggregate roots, and the above solution certainly violates this requirement.

Are there any other better ways to avoid this problem?

+4
source share
2 answers

Aggregate roots should be developed around the boundaries of the record - that is, everything that is usually written to the database in one batch / transaction. If you find that you need to individually preserve child entities that are not roots, it may be time to review your design and make your child object a separate aggregate root (since it has a separate recording boundary).

Instead, your original root node will not contain child entities, but rather references to them (since they are now aggregate roots by themselves, and links between aggregate roots must be through reference keys). It will also help in your lazy loading strategy.

Hope that helps :)

+5
source

Typically, ORM takes care of updating the entire aggregate in the database. It detects changes made to the extracted entities, and saves only the changed aggregate objects.

So, if you only add the child to the root directory, and you have no other modification in the aggregate. Then ORM will only insert a new record for the child and leave the root set and other child records.

-1
source

Source: https://habr.com/ru/post/1386682/


All Articles