You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 3.0 MySQL迁移添加外键约束时出错求助

MySQL外键约束错误(errno:150)在.NET Core Identity关联中的排查与解决

你在给CatalogProductBid关联ApplicationUser(继承自IdentityUser)时遇到的errno:150错误,本质是MySQL认为外键约束的定义不符合规则。结合你的代码和迁移脚本,我整理了几个最可能的原因及对应的解决思路:

1. 字段数据类型/字符集/排序规则不匹配

IdentityUser默认的Id字段是string类型,在MySQL中会被映射为NVARCHAR(450),并且通常使用utf8mb4字符集和对应的排序规则。而你的迁移脚本中添加的UserId字段没有明确指定字符集,可能和AspNetUsers.Id的字符集/排序规则不一致,这会导致MySQL无法创建外键。

解决方法:
修改迁移脚本,给UserId字段指定和AspNetUsers.Id完全一致的字符集和排序规则。比如:

migrationBuilder.AddColumn<string>(
    name: "UserId",
    table: "CatalogProductBids",
    nullable: false,
    defaultValue: "",
    annotations: new Dictionary<string, object>
    {
        ["MySql:CharSet"] = "utf8mb4",
        ["MySql:Collation"] = "utf8mb4_unicode_ci"
    });

你可以先执行SHOW CREATE TABLE AspNetUsers;命令查看AspNetUsers表的Id字段属性,确保UserId和它完全一致。

2. 现有数据不符合外键约束

你的迁移脚本给UserId设置了defaultValue: "",但AspNetUsers表中不存在Id为空字符串的用户。如果CatalogProductBids表中已经有数据,这些数据的UserId会被设为空字符串,而外键要求所有UserId必须在AspNetUsers.Id中存在,这就会触发错误。

解决方法:

  • 如果CatalogProductBids表还没有数据:可以直接移除defaultValue: "",或者把默认值改成一个已存在的用户Id。
  • 如果表中已有数据:先添加允许为空的UserId字段,更新所有数据的UserId为有效用户Id,再修改字段为非空并添加外键。修改后的迁移脚本示例:
protected override void Up(MigrationBuilder migrationBuilder)
{
    // 先添加可空的UserId
    migrationBuilder.AddColumn<string>(
        name: "UserId",
        table: "CatalogProductBids",
        nullable: true,
        annotations: new Dictionary<string, object>
        {
            ["MySql:CharSet"] = "utf8mb4",
            ["MySql:Collation"] = "utf8mb4_unicode_ci"
        });

    // 更新现有数据为有效用户Id(替换成你实际存在的用户Id)
    migrationBuilder.Sql("UPDATE CatalogProductBids SET UserId = 'your-valid-user-id' WHERE UserId IS NULL;");

    // 修改为非空字段
    migrationBuilder.AlterColumn<string>(
        name: "UserId",
        table: "CatalogProductBids",
        nullable: false,
        annotations: new Dictionary<string, object>
        {
            ["MySql:CharSet"] = "utf8mb4",
            ["MySql:Collation"] = "utf8mb4_unicode_ci"
        });

    migrationBuilder.CreateIndex(
        name: "IX_CatalogProductBids_UserId",
        table: "CatalogProductBids",
        column: "UserId");

    migrationBuilder.AddForeignKey(
        name: "FK_CatalogProductBids_AspNetUsers_UserId",
        table: "CatalogProductBids",
        column: "UserId",
        principalTable: "AspNetUsers",
        principalColumn: "Id",
        onDelete: ReferentialAction.Cascade);
}

3. 表引擎不支持外键

MySQL的MyISAM引擎不支持外键约束,而InnoDB才支持。如果CatalogProductBids表使用的是MyISAM引擎,就会导致外键创建失败。Identity默认创建的AspNetUsers表是InnoDB,但你自己的表可能不是。

解决方法:
在迁移脚本中确保CatalogProductBids表使用InnoDB引擎:

migrationBuilder.AlterTable("CatalogProductBids")
    .Annotation("MySql:Engine", "InnoDB");

把这段代码添加到Up方法的开头即可。

4. 主表字段不是主键/没有索引

虽然IdentityUser的Id默认是主键(自动带有索引),但如果你的AspNetUsers表被手动修改过,导致Id不是主键或没有索引,也会触发这个错误。不过这种情况比较少见,你可以用SHOW CREATE TABLE AspNetUsers;命令确认Id是主键。

先从数据类型/字符集不匹配和现有数据约束这两个最常见的原因排查,应该能解决问题。

内容的提问来源于stack exchange,提问作者Roel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 10:22:37