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

EF Core 2.2.1迁移更新失败:可空int转非空枚举类型问题

解决EF Core 2.2.1中修改可空int为非空枚举并设置默认值的迁移错误

这个问题的核心原因是:当你把可空列改成非空列时,现有表中已经存在NULL值的行,而EF Core自动生成的迁移脚本通常会先将列设置为NOT NULL,再添加默认值——这就导致了更新失败,因为NULL值无法存入非空列。

正确的解决步骤:

我们需要调整迁移脚本的执行顺序,先把现有NULL值的行填充为默认枚举值,再修改列的属性为非空并设置默认值。

1. 查看并修改自动生成的迁移文件

当你运行dotnet ef migrations add [MigrationName]生成迁移后,打开对应的迁移文件(比如XXXXXX_ChangeCountryCodeToEnum.cs),你会看到类似这样的代码:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterColumn<CountryCode>(
        name: "CountryCode",
        table: "User",
        nullable: false,
        defaultValue: CountryCode.Unknown,
        oldClrType: typeof(int?),
        oldNullable: true);
}

这段代码的问题在于,它直接把列改成非空并设置默认值,但现有NULL行还没处理。我们需要先添加SQL语句更新现有数据,再执行AlterColumn:

修改后的Up方法应该是这样:

protected override void Up(MigrationBuilder migrationBuilder)
{
    // 第一步:先将现有NULL的CountryCode更新为默认枚举值(假设Unknown对应的数值是0)
    migrationBuilder.Sql(@"
        UPDATE [dbo].[User]
        SET [CountryCode] = 0
        WHERE [CountryCode] IS NULL
    ");

    // 第二步:修改列属性为非空,并设置默认值
    migrationBuilder.AlterColumn<CountryCode>(
        name: "CountryCode",
        table: "User",
        nullable: false,
        defaultValue: CountryCode.Unknown,
        oldClrType: typeof(int?),
        oldNullable: true);
}

注意:这里的0要对应你CountryCode枚举中Unknown的实际数值,如果你的枚举是从1开始的,记得改成对应的数字。

2. 执行迁移

修改完成后,再运行dotnet ef database update,这次就能顺利执行了——因为先把所有NULL值填充为默认枚举值,再把列改成非空,同时设置新行的默认值。

额外注意点:

  • 确保你的CountryCode枚举在EF Core中正确映射:EF Core 2.2默认会把枚举映射为对应的int值,如果你有自定义数值,需要在实体配置中明确指定:
    builder.Property(e => e.CountryCode)
           .HasDefaultValue(CountryCode.Unknown)
           .HasConversion<int>(); // 明确指定转换为int类型
    
  • 如果你的表数据量很大,执行UPDATE语句时要考虑性能,可以分批处理,但一般小型项目直接执行即可。

这样修改后,数据库中的User表CountryCode列会变成非空,并且新插入的行如果没有指定该值,会自动使用Unknown作为默认值,同时现有数据也被正确填充。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:10:25