Note I’m not using C# (and thus EF). I am using TypeScript + Knex.
Let’s take the classic example of Sales Orders and Line Items. A single SaleOrder record can have multiple LineItems. My understanding is we would build a repository around the aggregate of Sale Order and Line Item. We would have Sale Order as the root aggregate. However, SaleOrders will want to be associated with a Customer and thus the SaleOrder will have a customerId as a reference. At some point we may want to lookup all Sale Orders from one or more Customers. We’d most likely want to achieve that doing by a join between the Customer and SaleOrder table (and maybe also LineItems) - you’re going to be fetching Customer Name, Address, Sale Order Id, Date, etc (and maybe also the details about the individual line items as well). Now you could use repositories and make multiple SQL queries but I’m guessing it’s more desirable to use a single JOIN query.
What is the ‘best’ way to achieve this? How can I compose repositories? Or is composing repositories is something you rarely want to do, and if you do when do you then you should be doing that in the application code.
Should I take the approach to always use repositories for updating data, and only use them for reading data most of the time. For example, when doing complex joins, drop back into SQL (though where should this SQL code live).
Eager to hear your thoughts
Thanks
Some particularly notable reads: This fella over at https://youtu.be/rtXpYpZdOzM?t=1030 explicitly says the query methods on the repository should NOT return an IQueryable (I guess the closest thing is Knex.QueryBuilder).
There is a (old) discussion about To return IQueryable or not return IQueryable : How can I query cross tables with Repository Pattern?
Implies that we should not be using a generic repository but choosing our aggregate around a group of entities that makes sense: https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design