我知道Code-First使用惯例进行模型绑定,并且这是list of conventions默认情况下可用(并且活动?)。如何用Entity Framework Code First确定多对多联结表名称?
它似乎的结表名了许多对许多关系的选择是有点乱..
所引用公约的用于确定交会表名?用于确定该名称的算法是什么?
我知道Code-First使用惯例进行模型绑定,并且这是list of conventions默认情况下可用(并且活动?)。如何用Entity Framework Code First确定多对多联结表名称?
它似乎的结表名了许多对许多关系的选择是有点乱..
所引用公约的用于确定交会表名?用于确定该名称的算法是什么?
我认为,对于许多一对多连接表的名称一般的规则是
ClassNameOfLeftEntity + PluralizedClassNameOfRightEntity
因此,如果第一个实体是User
,第二个是Role
连接表名字是UserRoles
。
这可能会受到删除PluralizingTableNameConvention
影响,但我不确定。
更大的问题是确定什么是“左”和什么是“正确的”实体。我认为它取决于几乎随机的因素,例如EF建立模型的顺序,而顺序依赖于实体之间的导航属性以及您在派生上下文中编写DbSet
的顺序。出于这个原因,强烈建议用Fluent API明确定义连接表名称。 EF模型中的小改动或改变上下文中组的顺序可让EF认为名称必须是RoleUsers
而不是前者UserRoles
。
这是reference to a similar answer。
编辑
另一个原因来定义许多一对多映射总是明确地用流利的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);
这将创建一个SQL JOIN在连接表的UserId
:ON Users.UserId = RoleUsers.UserId
。此连接不能使用连接表中的索引,而是会导致表扫描以检索表中用户的RoleIds行1,3和5。
这样的查询的性能更好的是将User
作为左实体,将Role
作为正确的实体,从而导致该对(UserId,RoleId)的聚集索引,这对于此类查询的性能更好。 (当然,您可以在上面的示例中创建第二个索引以提高性能。)要实现此目标,您必须指定Fluent API的映射。
因此,明智地选择左右实体并且不要将此决定留给EF是有意义的。