У меня есть 2 хранилища:
public class UserRepository : IUserRepository
{
public IQueryable<User> GetUsers();
}
public class PostRepository : IPostRepository
{
public IQueryable<Post> GetPosts();
}
Это может стать проблематичным.
Вы, вероятно, не хотите просто GetUsers
.Как вы говорите, вы хотите, чтобы дочерние сущности были загружены с агрегированным или высокоуровневым сущностью.
То, что произойдет, состоит в том, что в зависимости от контекста использования - какова ваша непосредственная цель - вы захотите вариации этогоUser
.Скорее всего, вы получите такие методы, как GetUsers
, 'GetUsersWithPosts
, GetUsersForImportantReport
, GetUsersForAttendingAnIceCreamSocial
и т. Д. И т. Д., Ad nauseam.
Чего не хватает, так это концепции роли.
Какую роль вы извлекаете для пользователя?Модель, которая явно здесь.
Начните с базового интерфейса для вашего агрегата.Основные свойства можно найти здесь
public interface IUser {
public Guid UserId { get; set; }
public string UserName { get; set; }
public IEnumerable<Posts> { get; set; }
}
Добавить интерфейсы для поддержки ролей, в которых вы будете использовать пользователя.
public interface IAddPostsToUser : IUser {
public void AddPost(Post post);
}
И ваш репозиторий можно определить так:
public interface IUserRepository {
User Get<TRole>(Guid userId) where TRole : IUser;
}
Теперь используйте эту роль, чтобы определить стратегию выборки;
public interface IFetchingStrategy<TRole> {
TRole Fetch(Guid id, IRepository<TRole> role)
}
Ваш репозиторий получит стратегии выборки через инъекцию или расположение службы и выборку вызовов.Вы можете передать репозиторий, чтобы обеспечить механизм для запроса FetchingStrategy, или FetchingStrategy может внедрить или определить, какие сервисы ему нужны для запроса.
Конечно, как именно ваш запрос будет зависеть от вашего ORM.
Но этот способ моделирования поможет избежать многих проблем с загрузкой графов сущностей в различных сценариях.