How can we tell Entity Framework about Aggregates?
- when saving an aggregate, save entities within the aggregate
- when deleting an aggregate, delete entities within the aggregate
- raise a concurrency error when two different users attempt to modify two different entities within the same aggreate
- when loading an aggregate, provide a consistent point-in-time view of the aggregate even if there is some time delay before we access all entities within the aggregate
(Entity Framework 4.3.1 Code First)
What is aggregate root entity?
An aggregate is a collection of one or more related entities (and possibly value objects). Each aggregate has a single root entity, referred to as the aggregate root. The aggregate root is responsible for controlling access to all of the members of its aggregate.
Can aggregate root reference another aggregate root?
[Evans] states that one Aggregate may hold references to the Root of other Aggregates. However, we must keep in mind that this does not place the referenced Aggregate inside the consistency boundary of the one referencing it. The reference does not cause the formation of just one whole Aggregate.
What is aggregate root CQRS?
Concretely, an aggregate will handle commands, apply events, and have a state model encapsulated within it that allows it to implement the required command validation, thus upholding the invariants (business rules) of the aggregate.
What is aggregate root event sourcing?
An Event Sourced Aggregate Root The aggregate root can be thought of as a number of functions that take value objects as arguments, execute the business logic and return events. Important: This means we never have any getters or expose the aggregate root's internal state in any way!
EF provides features which allows you defining your aggregates and using them:
- This is the most painful part. EF works with entity graphs. If you have an entity like Invoice and this entity has collection of related InvoiceLine entities you can approach it like aggregate. If you are in attached scenario everything works as expected but in detached scenario (either aggregate is not loaded by EF or it is loaded by different context instance) you must attach the aggregate to context instance and tell it exactly what did you changed = set state for every entity and independent association in object graph.
- This is handled by cascade delete - if you have related entities loaded, EF will delete them but if you don't you must have cascade delete configured on the relation in the database.
- This is handled by concurrency tokens in the database - most commonly either timestamp or rowversion columns.
- You must either use eager loading and load all data together at the beginning (= consistent point of view) or you will use lazy loading and in such case you will not have consistent point of view because lazy loading will load current state of relations but it will not update other parts of aggregate you have already loaded (and I consider this as performance killer if you try to implement such refreshing with EF).