【问题标题】:Multiple Primary Key to connect 2 tables多个主键连接2个表
【发布时间】:2020-09-24 17:37:43
【问题描述】:

我曾经在下面的 UserGroup 表中创建一个额外的 Id 列,然后我意识到这似乎是错误的。

用户:

Id    |   Name     |
--------------------
1     |   Tim      |
2     |   Willy    |
3     |   Mary     |
4     |   Jonathan |
5     |   Mary     |

组:

Id    |   Name   |
------------------
1     |   Bees   |
2     |   Ants   |

用户组:

Id    |   UserId   |  GroupId  |
--------------------------------
1     |   1        |  1        |
2     |   2        |  1        |
3     |   3        |  2        |
4     |   4        |  2        |
5     |   5        |  2        |

那么,请您澄清一下以下问题:

1) 由于 UserGroup 表中可能存在单个 UserId - GroupId 对,因此使用额外的 Id 列肯定是多余的,不需要使用此 Id 列,是这样吗?是否有特殊情况需要使用这个额外的 Id 列?

2) 删除 UserGroup 表中的 Id 列,我需要将两列都设为 PK。那么,我怎样才能在 EF Code First 中做到这一点?下面的定义是真的吗?

public class UserGroup
{
    [Key]
    public int UserId { get; set; }

    [Key]
    public int GroupId { get; set; }
}

【问题讨论】:

  • 请为您使用的确切数据库设置标签。并非所有关系型数据库
  • @SlavaRozhnev 我使用了其中三个,问题与所有这些都相关

标签: sql-server database oracle postgresql entity-framework


【解决方案1】:

上面的任何一种解决方案都有一个用例(有或没有 Id 列)。通常,如果表的目标是简单地关联两组数据,则不需要新的 Id,您可以使用复合键来定义 UserGroup 的 Id。阅读可以在这里找到:https://docs.microsoft.com/en-us/ef/core/modeling/keys?tabs=data-annotations。看起来您可能必须使用 Fluent API 而不是本文档中的数据注释。

还有另一种情况,在为用户和组形成 M 到 N 连接时,您可能需要一个 Id 列。如果您计划将任何数据连接到该连接,则使用 Id 来创建从其他表到用户组的外键会更容易。特别是在您的情况下,我认为可能会在您创建 UserGroups 后不久引入 UserGroupPermissions。您可以为此 ID 设置一个非聚集标识列,但我不推荐它。如果您希望表中包含带有 Id 的记录,最好尽可能将其用作聚集索引和主键。

【讨论】:

    【解决方案2】:

    一个表不可能有两个主键。 并且不需要创建第三个表作为 UserGroup 来映射表 User 和表 Group。只有在进行多对多关系时才需要创建 UserGroup 表的条件。 但是在您的情况下,一个用户只有一个组,而一个组可以有多个用户,这意味着存在多对一关系。

    因此,您只需在 User 表中添加新列作为 GroupId 并将其设为外键。 并删除该 UserGroup 表。

    谢谢。

    【讨论】:

      【解决方案3】:

      你问了 2 个问题:

      答案 1 - 在您的场景中,它不是必需的,因为您将此表保留为 UserGroup 表之间的关系。在某些特定条件下可能需要 i。 e.您想为您的 usergroup 映射等保留审计跟踪。

      答案 2 - 要保持关系的唯一性,您需要创建 Composite Key。你的定义应该是这样的:

      public class UserGroup
      {
          [Key, Column(Order=1) ]
          public int UserId { get; set; }
      
          [Key, Column(Order=2) ]
          public int GroupId { get; set; }
      }
      

      Tutorial供您参考

      【讨论】:

      • 这正是我想学习的,非常感谢这些很好的解释。
      • 另一方面,您能否将其与@Yogendra 提到的方法进行比较? 不创建 UserGroup 表而只是在 User 表中添加新列作为 GroupId 并使其成为外键呢?
      • 如果一个用户严格只能与一个组链接,也可以采用这种方法。如果一个用户可以与多个组链接,它将不起作用
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      • 2022-10-03
      • 1970-01-01
      相关资源
      最近更新 更多