Я думаю, общее правило для имени таблицы объединения «многие ко многим»:
ClassNameOfLeftEntity + PluralizedClassNameOfRightEntity
Итак, если первая сущность - User
а второе - Role
имя таблицы соединений - UserRoles
.
Возможно, на это может повлиять удаление PluralizingTableNameConvention
, но я не уверен.
большая проблема состоит в том, чтобы определить, что такое «левый» и что такое «правый» объект.Я думаю, что это зависит от почти случайных факторов, таких как порядок, в котором EF строит модель, в которой, в свою очередь, зависит от свойств навигации между сущностями и порядка, в котором вы записали DbSet
в производном контексте.По этой причине настоятельно рекомендуется явно определять имя таблицы соединений с помощью Fluent API.Небольшое изменение в вашей модели или изменение порядка наборов в вашем контексте может привести к тому, что EF будет думать, что имя должно быть RoleUsers
вместо прежнего UserRoles
.
Вот ссылка нааналогичный ответ .
Редактировать
Еще одна причина для определения сопоставления «многие ко многим» всегда явным образом с помощью Fluent API (не так уж много общего с именем таблицы)вопрос, но больше к вопросу, что должно быть левым, а что правым объектом) - производительность.
Таблица соединений имеет составной первичный ключ и кластеризованный индекс для этого ключа (по крайней мере, в SQL Server).Теперь предположим, что имя таблицы будет RoleUsers
, а левая сущность - Role
, а правая сущность - User
, поскольку, возможно, какой-то разработчик решил отсортировать наборы по алфавиту в контексте:
public DbSet<Role> Roles { get; set; }
public DbSet<User> Users { get; set; }
.Записи таблицы присоединения будут выглядеть так:
RoleId UserId
----------------
1 1
1 2
2 1
2 2
3 1
3 2
Теперь, возможно, большинство запросов в вашем приложении заинтересованы в получении ролей для данного пользователя.Но вам не часто или никогда не интересно получать всех пользователей для данной роли.Роли данного пользователя могут быть запрошены с помощью Include
:
var user = context.Users.Include(u => u.Roles).Single(u => u.UserId == 1);
Это создаст JOIN в SQL на UserId
в таблице соединений: ON Users.UserId = RoleUsers.UserId
.Это соединение не может использовать индекс в таблице соединений, но вместо этого приводит к сканированию таблицы для получения строк 1, 3 и 5 в таблице для пользовательских RoleIds.
Лучше для выполнения таких запросов, как это иметьUser
как левая сущность и Role
как правая сущность, что приводит к кластерному индексу для пары (UserId, RoleId), который лучше подходит для выполнения таких запросов.(Конечно, вы могли бы создать второй индекс в приведенном выше примере для повышения производительности.) Для достижения этого вы должны указать отображение с помощью Fluent API.
Итак, имеет смысл выбирать левый и правый объект с умоми не оставлять это решение EF.