EF Core迁移生成错误枚举:为何出现旧蛇形命名枚举?
问题原因及解决方案
核心矛盾
你遇到的问题源于Npgsql的默认命名约定与你手动指定的列类型不匹配:
- Npgsql会自动将C#帕斯卡命名的枚举(如
AutoStatus)转换为蛇形命名的PostgreSQL枚举类型(auto_status),这就是迁移文件里出现auto_status的原因。 - 但你在实体映射中用了
.HasColumnType(nameof(AutoStatus)),这会让EF尝试使用小写的autostatus作为列类型,而数据库实际要创建的是auto_status,两者不一致就触发了42704: type "autostatus" does not exist错误。
解决方案
有两种方式可以解决这个不匹配问题:
方案1:显式指定PostgreSQL枚举名
在注册枚举时,手动指定数据库中要使用的枚举名称,让它和你HasColumnType指定的名称一致:
modelBuilder .HasPostgresEnum<AutoStatus>("autostatus") // 显式指定数据库枚举名为autostatus .HasPostgresEnum<AnotherEnum>("anotherenum") .HasPostgresEnum<AndAnotherEnum>("andanotherenum"); modelBuilder.Entity<Auto>(entity => entity.Property(e => e.Status).HasColumnName("status") .HasConversion<string>() .HasDefaultValueSql(AutoStatus.InAssembly.ToString()) .HasColumnType(nameof(AutoStatus)); // 这里对应autostatus );
方案2:修改列类型为蛇形命名
保持Npgsql的默认命名约定,将HasColumnType改为蛇形的枚举名:
modelBuilder.Entity<Auto>(entity => entity.Property(e => e.Status).HasColumnName("status") .HasConversion<string>() .HasDefaultValueSql(AutoStatus.InAssembly.ToString()) .HasColumnType("auto_status"); // 匹配默认生成的蛇形枚举名 );
额外说明
即使你项目中没有旧的蛇形枚举代码,Npgsql的默认约定依然会生效——它是基于CLR类型名自动转换命名规则,不是依赖你代码中有没有旧枚举引用。
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

