I have the following layers involved in this question:
A lot of times it's really straight forward: Repository layer queries database via Entity Framework and returns IList<SomeDomainEntity>
to caller which was Service Layer. The type returned is a type defined in the Domain Model.
The problem I'm running into is when I need to query across POCOs A,B, and C and get data from all to be returned. Since I don't handle any logic in the repository I need to return this data back to the Service layer to be processed (either directly or more likely by calling some logic on domain model). However I don't have a single type anymore from the results of the repository query to return to the caller.
An anonymous type of course handles this in examples I see, but since I'm not processing that logic from returned data directly in the Repository and it needs to be returned, I need a physical type to return. Here are some solutions I thought of but not sure I like any:
I can't be the only one querying across multiple entities to get a conglomeration of data back that needs to be added to a type and returned to the caller. What is a common practice or standard way of going about this to solve my problem?
Thanks!
If those entities are related and you query all of them in one place then you should try to find an aggregate root of them in your domain model or if it doesn't exist yet you should introduce a new one, as you said in the first option. This is not wrong until it makes sense. It should model a domain concept and you probably have one because you created that repository method.
If those entities are not related (well, probably related in some way, but not that tightly as above) and you just want to get them in one go then you should handle that in the service layer where you can use multiple repositories and compose a result object.
You probably heard of the concept of navigation properties and eager loading but I write it here because it may be another answer to your question (I don't see your domain model)
I wouldn't go with your third suggestion (create viewmodels in the repository) because it breaks the separations.
Different entities can relate to each other whithout one of them being an aggregate root. Services are used to these kind of queries. I usually do something like this:
public class MyService
{
IEnumerable<UserWithMessages> Find()
{
var messages = _messageRepository.FindAll();
var userIds = _messages.Select(x => x.UserId).Distinct().ToArry();
var users = _userRepository.Find(userIds);
return users.Select(x => new UserWithMessages(x, messages.Where(x => x.UserId == x.Id));
}
}
It's just two DB queries which can utilize indexes in the DB. So It should be pretty fast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With