【问题标题】:EF6 database first map one to one relationshipEF6 数据库首先映射一对一关系
【发布时间】:2016-05-09 14:13:42
【问题描述】:

在我的数据库中,我通过对外键表进行唯一约束来实施一对一的关系。这被 Sql Server Management Studio 正确识别为一对一关系:

我的问题是 EF6 没有将此识别为一对一关系并在 Person 类上生成一个 Collection:

如果 t4 模板中的 itemCollection 包含唯一键信息,我可以轻松地修改 T4 模板以在表上有唯一键时不生成集合。但它们只包含外键信息。我猜这是因为 edmgen 工具没有从数据库中提取这些信息。

有没有办法强制该工具在数据库中包含所有约束,以便我可以在 t4 模板中使用这些信息?

【问题讨论】:

    标签: entity-framework-6 edmx ef-database-first


    【解决方案1】:

    我认为这里最好的解决方案是重新考虑您的表格和关系。

    选项 1: 如果这是一对一的关系,你能把所有的东西都放在一张桌子上吗?

    选项 2: 取出 PersonId 列。如果这确实是 1 对 1,甚至是“1 对 0 或 1”关系,那么这些表应该共享一个主键。关系应该是Id和Id之间的关系。如果这样做,EF6 将正确识别它。

    【讨论】:

    • 谢谢你。选项 2 适用于 1 到 0..1,0..1 端的主键也是外键。不幸的是,它不适用于 0..1 到 0..1 的关系,即实体独立存在并随后链接的任何情况,因为实体通常不会具有相同的主键。我不确定我们是否有针对这种情况的好的解决方案。
    • 考虑到这一点,我想对于各种1对1的关系,可能有一个通用的解决方案。我今天会尝试一下并发布我的发现。
    【解决方案2】:

    选项 3:在外键上放置唯一约束或唯一索引。

    外键的唯一性将关系的那一侧的基数限制为最多 1。我测试并确认在数据库优先方案中使用 Sql Server 和 EF Core 5.0 时,这是正确的基数。

    为什么选项 3 可能更受欢迎

    选项 3 适用于 1 到 0..1 和 0..1 到 0..1 关系。这意味着您可以在现有数据库上轻松使用它,而无需更改它们。

    0..1 到 0..1 的关系确实很自然地发生,当实体在被链接之前可以以自己的权利存在时。扩展上面的示例,如果我们允许与任何人无关的系统用户帐户,并且我们还有尚未为其创建用户帐户的人,那么最好用 0..1-to 建模-0..1 关系。

    如果您确定需要 1 对 0..1 的关系,选项 2 仍然是一个不错的选择。您可以稍后迁移到选项 3,但工作量会更大。

    补充说明

    如果您正在实现 [0,1] 到 [0,1] 关系,那么您的外键字段将为空。可空外键上的 UNIQUE 约束通常允许多行包含 NULL,因为 NULL 不是传统 SQL 中的值。但是,Sql Server 是一个例外,它只允许一行在外键中保存 NULL。

    解决方案是在 Sql Server 上使用条件 UNIQUE INDEX 而不是 UNIQUE CONSTRAINT。您的条件应仅将索引应用于外键中具有非空值的行。

    您可以使用如下 SQL 创建这样的索引。

    CREATE UNIQUE INDEX IX_User_Person
    ON User (PersonId) WHERE PersonId IS NOT NULL;
    

    【讨论】:

      【解决方案3】:

      兄弟听着。你是对的。我有同样的问题。在一列上使用主键和外键。不要将主键和外键分成两列。这肯定会解决你的问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-10
        • 1970-01-01
        相关资源
        最近更新 更多