I know that Code-First uses conventions for model binding, and that this is the list of conventions that are available (and active?) by default.
It seems that the selection of the junction table name for Many-to-Many relationships is a little bit random..
Which of the referenced conventions is used to determine the junction table name? What is the algorithm used to determine that name?
I think, the general rule for the many-to-many join table name is
ClassNameOfLeftEntity + PluralizedClassNameOfRightEntity
So, if the first entity is
Userand the second isRolethe join table name isUserRoles.It is possible that this can be influenced by removing the
PluralizingTableNameConventionbut i am not sure.The bigger problem is to determine what is the “left” and what the “right” entity. I think it depends on almost random factors, like the order which EF builds the model in which in turn depends on navigation properties between entities and the order in which you have written the
DbSets in your derived context. For this reason it is strongly recommended to define the join table name explicitely with Fluent API. A small change in your model or changing the order of the sets in your context can EF let think the name must beRoleUsersinstead of the formerUserRoles.Here is a reference to a similar answer.
Edit
Another reason to define the many-to-many mapping always explicitely with Fluent API (not that much related to the table name question but more to the question what should be the left and what the right entity) is performance.
The join table has a compound primary key and a clustered index on that key (at least in SQL Server). Now assume the table name would be
RoleUsersand the left entity isRoleand the right entity isUserbecause perhaps some developer decided to sort the sets alphabetically in the context:The join table entries would look like this:
Now, possibly the majority of queries in your application are interested in getting the roles for a given user. But you are not often or never interested to get all users for a given role. The roles of a given user could be queried by an
Include:This would create a JOIN in SQL on the
UserIdin the join table:ON Users.UserId = RoleUsers.UserId. This join cannot use the index in the join table but instead results in a table scan to retrieve row 1, 3 and 5 in the table for the user’s RoleIds.Better for performance of queries like this is to have the
Useras the left entity and theRoleas the right entity, resulting in a clustered index for the pair (UserId, RoleId) which is better for performance of such queries. (You could of course create a second index in the example above to improve the performance.) To achieve this you must specify the mapping with Fluent API.So, it makes sense to choose the left and right entity wisely and to not leave this decision to EF.