Каков рекомендуемый способ возврата специальных (настраиваемых в каждом конкретном случае) данных из репозитория, которые не соответствуют каким-либо объектам модели или расширяют некоторые из них?
Примером 101 может быть вездесущее приложение hello word: система блогов. Предположим, вы хотите загрузить список сообщений, где запись сообщения содержит некоторую дополнительную информацию, которой нет в сущности сообщения. Допустим, это количество комментариев, а также дата и время последнего комментария. Это было бы очень тривиально, если бы кто-то использовал старый добрый SQL и считывал данные непосредственно из базы данных. Как я должен сделать это оптимально, используя шаблон репозитория, если я не могу позволить себе загружать все коллекции комментариев для каждого поста, и я хочу сделать это одним обращением к базе данных? Есть ли какой-нибудь широко используемый шаблон для этой ситуации? Теперь представьте, что у вас есть умеренно сложное веб-приложение, в котором для каждой страницы требуются немного разные пользовательские данные, а загрузка полных иерархий невозможна (производительность, требования к памяти и т. д.).
Несколько случайных идей:
Добавьте список свойств к каждой модели, которые могут быть заполнены пользовательскими данными.
Объекты модели подкласса в каждом конкретном случае и создание пользовательских считывателей для каждого подкласса.
Используйте LINQ, создавайте специальные запросы и читайте анонимные классы.
Примечание. Я попросил аналогичный вопрос недавно, но он показался слишком общим и не привлек большого внимания.
Пример:
Основываясь на предложениях в ответах ниже, я добавляю более конкретный пример. Вот ситуацию, которую я пытался описать:
IEnumarable<Post> posts = repository.GetPostsByPage(1);
foreach (Post post in posts)
{
// snip: push post title, content, etc. to view
// determine the post count and latest comment date
int commentCount = post.Comments.Count();
DateTime newestCommentDate = post.Comments.Max(c => c.Date);
// snip: push the count and date to view
}
Если я не сделаю ничего лишнего и воспользуюсь готовым ORM, это приведет к n+1 запросам или, возможно, к одному запросу, загружающему все сообщения и комментарии. Но в идеале я хотел бы иметь возможность просто выполнить один SQL, который будет возвращать одну строку для каждого сообщения, включая заголовок сообщения, тело и т. д., а также количество комментариев и дату последнего комментария в одном и том же. Это тривиально в SQL. Проблема в том, что мой репозиторий не сможет прочитать и поместить этот тип данных в модель. Куда идут максимальные даты и количество?
Я не спрашиваю, как это сделать. Вы всегда можете сделать это как-нибудь: добавить дополнительные методы в репозиторий, добавить новые классы, специальные сущности, использовать LINQ и т. д., но я думаю, что мой вопрос заключается в следующем. Почему шаблон репозитория и правильная разработка, основанная на модели, так широко распространены, но все же они, кажется, не решают этот, казалось бы, очень распространенный и базовый случай.