【问题标题】:How is the many-to-many junction table name determined with Entity Framework Code First?Entity Framework Code First 如何确定多对多联结表名称?
【发布时间】:2016-12-22 18:05:08
【问题描述】:

我知道 Code-First 使用约定进行模型绑定,这是默认情况下可用(并且是活动的?)的 list of conventions

似乎多对多关系的联结表名称的选择有点随机..

使用哪些参考约定来确定联结表名称?用于确定该名称的算法是什么?

【问题讨论】:

    标签: .net entity-framework-4.1 code-first


    【解决方案1】:

    我认为,多对多连接表名的一般规则是

    ClassNameOfLeftEntity + PluralizedClassNameOfRightEntity

    所以,如果第一个实体是User,第二个是Role,则连接表名称是UserRoles

    这可能会受到删除PluralizingTableNameConvention 的影响,但我不确定。

    更大的问题是确定什么是“左”,什么是“右”实体。我认为这几乎取决于随机因素,例如 EF 构建模型的顺序,而模型又取决于实体之间的导航属性以及您在派生上下文中编写 DbSets 的顺序。因此,强烈建议使用 Fluent API 显式定义连接表名称。您的模型中的一个小改动或在您的上下文中更改集合的顺序可以 EF 让我们认为名称必须是 RoleUsers 而不是之前的 UserRoles

    这是reference to a similar answer

    编辑

    始终使用 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);
    

    这将在连接表中的UserId 上在 SQL 中创建一个 JOIN:ON Users.UserId = RoleUsers.UserId。此连接不能使用连接表中的索引,而是会导致表扫描以检索表中的第 1、3 和 5 行以获取用户的 RoleId。

    更好的查询性能是将User 作为左实体,Role 作为右实体,从而为 (UserId, RoleId) 对生成一个聚集索引,这对于性能更好此类查询。 (您当然可以在上面的示例中创建第二个索引来提高性能。)为此,您必须使用 Fluent API 指定映射。

    因此,明智地选择左右实体而不是将决定权交给 EF 是有意义的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-06
      • 2011-09-17
      • 2021-02-08
      • 2013-01-12
      • 2015-12-21
      • 1970-01-01
      相关资源
      最近更新 更多