【问题标题】:EF Core 6 - How to add AUTO_INCREMENT to a column used by other foreign keysEF Core 6 - 如何将 AUTO_INCREMENT 添加到其他外键使用的列
【发布时间】:2022-01-20 03:34:34
【问题描述】:

我有一个 EF Core Code-First 表,例如:

public class Entity
{
    public byte ID { get; set; }
    public string Name { get; set; }
    ...
}

还有许多其他表格:

public class Others 
{
    ...
    public byte EntityID { get; set; }
    ...
    [ForeignKey("EntityID")]
    public Entity Entity { get; set; }
}

我只知道如果您使用byte 作为主键,EF Core 6 不会设置AUTO_INCREMENT,所以我尝试添加它:

public class Entity
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public byte ID { get; set; }

    public string Name { get; set; }
    ...
}

迁移cs是:

migrationBuilder.AlterColumn<byte>(
                name: "ID",
                table: "Entity",
                type: "tinyint unsigned",
                nullable: false,
                oldClrType: typeof(byte),
                oldType: "tinyint unsigned")
                .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);

但是当我尝试迁移时,我得到了这个错误:

MySqlConnector.MySqlException:无法更改列“ID”:用于表“Others”的外键约束“FK_Others_Entity_EntityID”

我只想添加AUTO_INCREMENT,这样外键应该是安全的。如何添加它,或者是否有办法让 EF Core 6 迁移仅在此迁移期间关闭外键检查?

【问题讨论】:

  • 如何将字节设置为主键。字节存储的值有限,例如 1 和 0。为此使用 int 或 Varachar(limit)。
  • byte是mysql中的tinyint,取值范围是0到255,在某些情况下足够了,可以节省空间。
  • 外键检查可以使用migrationBuilder的Sql函数。 migrationBuilder.Sql("ALTER TABLE Entity NOCHECK CONSTRAINT ALL")
  • 如果您担心节省空间,请在字符串上设置最大长度。我真的建议在您的模型上切换到数字数据类型。当前的解决方案虽然在技术上可行,但增加了不必要的难度和复杂性。
  • 我实际上在字符串上设置了一个最大长度,只是在问题中发出,因为它不相关。

标签: c# mysql entity-framework-core ef-core-6.0


【解决方案1】:

正如@Kiran Joshi 的评论,我可以使用原始SQL 来暂停外键检查,MySQL 版本是:

migrationBuilder.Sql("SET FOREIGN_KEY_CHECKS=0");

把这个和migrationBuilder.Sql("SET FOREIGN_KEY_CHECKS=1");(可能不需要)放在UpDown中就可以了。

【讨论】:

    【解决方案2】:

    您最好的选择可能是删除外键约束,修改列,然后重新添加外键约束。这个方法详细描述in this answer

    此列是表的主键吗?是否允许空值?

    我的建议是您考虑在 EF 迁移之外执行此更改,即使您更新迁移以在未来的干净数据库部署中实施更改。删除约束来操纵模式可能会产生意想不到的严重后果。备份是您的朋友。

    【讨论】:

    • 相关外键约束过多。有没有办法轻松处理 30 个外键?
    • @RomulusUrakagiTs'ai - 这里最简单的解决方案可能是删除您的数据库和现有迁移并重新启动您的架构。删除所有迁移后,添加一个迁移,它将使用所需的列规范创建表。
    • 删除数据库并不总是一件容易的事,即使有一些备份/恢复机制。
    • 如果系统尚未投入生产,从头开始重新开始架构迁移可能是最好的方法。您很难在当前状态下进行可重复的迁移。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 2011-06-15
    • 2011-06-29
    • 2021-12-25
    相关资源
    最近更新 更多