Рассмотрим следующий пример:
var users = new user[]
{
new user()
{
Name = "Jan",
Roles = new Role[]
{
new Role() {Name = "Supervisor},
new Role() {Name = "Teacher"},
}
},
new user()
{
Name = "Pierre",
Roles = new Role[]
{
new Role() {Name = "Student"},
new Role() {Name = "Scholar"},
}
}
}
как я могу заказать пользователей в соответствии с их именами ролей?
Что вы имеете в виду?Вы хотите пользователей с ролями, где роли упорядочены по имени?Или вы хотите, чтобы роли упорядочивались по имени вместе с их пользователями?
В любом случае, если вы следовали первым соглашениям кода платформы сущностей, ваши классы для многих для многих будут похожи на следующие:
class User
{
public int Id {get; set;}
public string Name {get; set;}
// every User has zero or more Roles (many-to-many)
public virtual ICollection<Role> Roles {get; set;}
}
class Role
{
public int Id {get; set;}
public string Name {get; set;}
// every Role has zero or more Users (many-to-many)
public virtual ICollection<User> Users {get; set;}
}
class MyDbcontext : DbContext
{
public DbSet<User> Users {get; set;}
public DbSet<Role> Roles {get; set;}
}
В структуре сущностей столбцы таблиц представлены не виртуальными свойствами.Виртуальные свойства представляют отношения между таблицами.
Этого достаточно для того, чтобы структура сущностей обнаружила, что вы намеревались установить отношение "многие ко многим".Entity Framework создаст для вас соединительную таблицу и будет использовать эту таблицу при необходимости.
Возможно, вам потребуются другие имена для таблиц и столбцов, в этом случае вам понадобится свободный API или атрибуты.Однако классы будут похожи.
Получить пользователей с их ролями, упорядоченными по имени
var result = dbContext.Users
.Where(user => ...) // only if you don't want all Users
.Select(user => new
{
// select only the properties that you plan to use
Id = user.Id,
Name = user.Name,
Roles = user.Roles
.Where(role => ...) // only if you don't want all Roles
.OrderBy(role => role.Name)
.Select(role => new
{ // again: select only the properties you plan to use
Id = role.Id,
Name = role.Name,
})
.ToList(),
});
Одна из более медленных частей запроса - это транспортировка выбранногоданные для вашего локального процесса.Следовательно, не стоит выбирать больше данных, чем вы планируете использовать.Если вы используете include
для извлечения данных, вы выбираете все свойства класса, включая внешние ключи.
Например, если вы берете Учителя с Id 4 со всеми его учениками, вы знаете, что каждый из его 1000 Students
будет иметь внешний ключ TeacherId
со значением 4. Какая трата длятранспортируйте все эти внешние ключи!
Совет: при запросе данных используйте Select
, чтобы выбрать свойства, которые вы фактически планируете использовать.Используйте Include
только если вы планируете изменить включенный объект