У меня есть две сущности:
- Местоположение
- Опубликовать
Это 1..* между Location и Post.
Местоположение является абстрактным, у меня есть много производных объектов, таких как Город. Я использую наследование Table-Per-Type для своей модели.
Я пытаюсь написать следующий запрос: (упрощенный)
- Получите 20 лучших городов и включите «Пост с самым высоким рейтингом» (самый высокий рейтинг).
Итак, Location имеет навигационное свойство, называемое Posts.
Имейте в виду, что я отключаю ленивую загрузку, поэтому я должен быстро загрузить или выполнить два запроса.
Итак, вот запрос, который у меня сейчас есть. Имейте в виду, мне нужно вернуть ICollection<Location>
из этого метода:
public ICollection<Location> FindTopTwentyLocations()
{
var results = new List<Location>();
var cities = locationRepository
.Find()
.OfType<City>()
.Select(x => new
{
Location = x,
TopPost = x.Posts.OrderByDescending(r => x.Rating).FirstOrDefault()
}).Take(20).ToList();
foreach (var city in cities)
{
var aggregatedCity = city.Location;
aggregatedCity.Posts = new List<Post> { aggregatedCity.TopPost };
results.Add(city);
}
return results;
}
По сути, я беру первые 20 городов, проецирую их в анонимный тип, чтобы я мог захватить верхнюю публикацию, а затем перебираю эту коллекцию анонимных типов, чтобы запихнуть публикацию обратно в объект «City», для добавления к возвращаемому типу List<Location>
.
- Я не могу использовать
.Include
, так как это вернет все сообщения. - Я не хочу выполнять 2 запроса
- Я должен использовать проекцию анонимного типа, иначе он выдаст ошибку EF (не может перевести запрос)
Имея в виду эти моменты, есть ли лучший способ сделать это? Я вполне доволен запросом var cities
, но мне не очень нравится зацикливание/копирование свойств анонимного типа в объект моей модели.
Любые идеи?
ИЗМЕНИТЬ
Я также заметил, что проекция на анонимный тип теряет нетерпеливо загруженные ассоциации Location, которые я получаю.
E.g
var query = locationRepository.Find().OfType<City>().Include("State").ToList();
работает - вернулись все "государственные" ассоциации.
но:
var query = locationRepository.Find().OfType<City>().Include("State").Select(x => new {
Location = x,
TopPost = x.Posts.OrderByDescending(r => x.Rating).FirstOrDefault()
}).ToList();
В результате все ассоциации «Состояние» становятся нулевыми.
странно!