Normand Bedard
Normand Bedard

Reputation: 2685

DDD - What about custom SQL querying multiple aggregates inside a single repository method?

I design my aggregates to enforce invariants and business rules. I always consider my aggregate as a "write model" / "transaction model".

Considering that, I always feel free to expose "complex" GET methods in my repositories, using custom SQL / Linq, because I am not altrering data.

For example, consider two fictive aggregate roots (Student and School), using only reference ids between them. If I want to send an email to all students of a school, I'd typically use a domain service that executes this, for performance purpose:

  1. Calls a repository with a method like "GetAllStudentEmailAddressesForSchool(Guid schoolId)"
  2. Sends an email for each student

Of course, the repository implementation would required to do a "complex" query (JOIN) on the two aggregates.

The typical alternative would be to orcherstrate multiple calls on repositories in a domain service:

  1. Fetch the school from the ISchoolRepository
  2. Foreach StudentId of the School, call the IStudentRepository

(Of course it depends of the aggregate modelization, but the basic concept remains).

I had a lot debates with colleagues about this, many argue that the first approach leaks domain business outside the domain (aka in the infrastructure layer, in the repository implementation).

For me, it is a simple filtering strategy, the same way a ISchoolRepository would expose a method like "GetSchoolsFromCity(Guid cityId)". The fact that the filtering occurs on a single aggregate instead of two changes nothing.

Any opinions about that?

Upvotes: 0

Views: 481

Answers (2)

choquero70
choquero70

Reputation: 4754

you don't have to use the domain model , ie the aggregates, when implementing the query. You can query the database and fetch the data you need into a plain custom dto according to the data you need. This way you segregate write model and resd model.

Upvotes: 1

Chad Thomas
Chad Thomas

Reputation: 1

First off, don't get terribly hung up on the perfect way to have aggregates interact. There often is no single right answer, just a bunch of wrong ones.

Second, you have described your aggregates and repositories, but not your bounded context(s). From what I know about schools, it sort of hard to have one that does not have students. How do you have that modeled?

Finally, as you stated, this is read model stuff. It is perfectly fine to have a LINQ query that gets all student emails for a given school. Feed that result into a service that sends the emails and get on with it.

Upvotes: 0

Related Questions