Я был в дискуссии с @AbdouMoumen, но в конце концов я решил дать свой собственный ответ: -)
Его ответ работает, но в этом коде есть две проблемы с производительностью (оба в ответекак в оригинальном вопросе).
Сначала код загружает ВСЕ контакты в БД.Это может быть или не быть проблемой, но в целом я бы рекомендовал НЕ делать этого.Многие современные элементы управления поддерживают подкачку / фильтрацию «из коробки», так что вам лучше поставить еще не оцененный IQueryable<T>
вместо List<T>
.Однако, если вам нужно все в памяти, вы должны отложить ToList
до последнего возможного момента.
Во-вторых, в ответе AbdouMoumen есть так называемая проблема «ВЫБОР N + 1».По умолчанию Entity Framework будет использовать отложенную загрузку для получения дополнительных свойств.Т.е. свойство Areas не будет извлечено из базы данных, пока к нему не будет получен доступ.В этом случае это произойдет в элементе управления for
loop, в то время как он упорядочивает результат по имени.
Откройте SQL Server Profiler, чтобы понять, что я имею в виду: вы увидите инструкцию SELECT для всех контактов и дополнительную инструкцию SELECT для каждого контакта, которая выбирает области для этого контакта.
Гораздо лучшим решением было бы следующее:
public void LoadAllContacts()
{
using (var db = new ContextDB())
{
// note: no ToList() yet, just defining the query
var contactsQuery = db.LocalContacts
.OrderBy(x => x.Areas
.OrderBy(y => y.Name)
.First().Name);
// fetch all the contacts, correctly ordered in the DB
grdItems.DataSource = contactsQuery.ToList();
grdItems.DataBind();
}
}