Стратегия загрузки данных / синтаксис в EF4
Долгое время скрывался, впервые отправляю сообщения и изучаю EF4 и MVC3.
Мне нужна помощь, чтобы убедиться, что я использую правильную стратегию загрузки данных в этом случае, а также некоторую помощь в завершении некоторых деталей запроса. В настоящее время я использую готовый подход к загрузке, описанный здесь для некоторого представления "панели мониторинга", которое требует небольшого количества данных из приблизительно 10 таблиц (все имеют отношения FK).
var query = from l in db.Leagues
.Include("Sport")
.Include("LeagueContacts")
.Include("LeagueContacts.User")
.Include("LeagueContacts.User.UserContactDatas")
.Include("LeagueEvents")
.Include("LeagueEvents.Event")
.Include("Seasons")
.Include("Seasons.Divisions")
.Include("Seasons.Divisions.Teams")
.Where(l => l.URLPart.Equals(leagueName))
select (l);
model = (Models.League) query.First();
Однако мне нужно сделать дополнительную фильтрацию, сортировку и формирование данных, которые я не смог обработать. Вот мои главные потребности / проблемы с этого момента:
Несколько дочерних объектов все еще нуждаются в дополнительной фильтрации, но я пока не смог понять синтаксис или лучший подход. Пример: "TOP 3 LeagueEvents.Event WHERE StartDate >= getdate() ORDER BY LeagueEvents.Event.StartDate"
Мне нужно отсортировать некоторые поля. Примеры: ORDERBY Seasons.StartDate, LeagueEvents.Event.StartDate, LeagueContacts.User.SortOrder и т. Д.
Я уже очень обеспокоен общим размером SQL, генерируемого этим запросом, и количеством соединений, и думаю, что мне может понадобиться совсем другой подход к загрузке данных (явная загрузка? Multiple QueryObjects? POCO?)
Будем очень благодарны за любые замечания, указания или советы о том, как решить эти остающиеся потребности, а также обеспечить наилучшую производительность.
2 ответа
Ваша забота о размере запроса и размере набора результатов ощутима.
Как упомянул @BrokenGlass, EF не позволяет вам выполнять фильтрацию или упорядочивание включений. Если вы хотите упорядочить или отфильтровать отношения, вы должны использовать проекцию либо на анонимный тип, либо на собственный (не сопоставленный) тип:
var query = db.Leagues
.Where(l => l.URLPart.Equals(leagueName))
.Select(l => new
{
League = l,
Events = l.LeagueEvents.Where(...)
.OrderBy(...)
.Take(3)
.Select(e => e.Event)
...
});
К сожалению, EF не позволяет выборочно загружать связанные объекты, используя его свойства навигации, он всегда загружает все Foos
если вы укажете Include("Foo")
,
Вам нужно будет присоединиться к каждому из связанных лиц, используя ваш Where()
пункты в качестве фильтров, где они применяются.