.NET 8 EF中TPC继承模式下Model ID无法自动生成问题
问题根源
采用TPC(Table-per-concrete-type)映射策略时,每个具体实体类对应独立的数据表,基类的Id字段会被复制到每个派生类的表中。虽然你在DataContextModelSnapshot里看到Id标记了ValueGeneratedOnAdd,但EF Core针对MySQL的TPC配置默认不会自动给派生表的Id加上AUTO_INCREMENT——MySQL的自增特性需要显式在表字段上声明,而TPC模式下EF没有将这个配置正确同步到派生表的结构中。
具体解决步骤
1. 给派生类的Id显式配置自增逻辑
在OnModelCreating方法中,针对DefinitieBehandelaar这类派生类,明确指定Id的生成策略,绑定MySQL的自增特性:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // 启用TPC映射,基类不生成独立表 modelBuilder.Entity<DatabaseObject>().UseTpcMappingStrategy(); // 关键配置:给派生类的Id绑定MySQL自增逻辑 modelBuilder.Entity<DefinitieBehandelaar>() .Property(b => b.Id) .ValueGeneratedOnAdd() .UseIdentityColumn(); // 告诉EF Core使用MySQL的自增列特性 }
如果你的Id是long类型,无需额外调整,UseIdentityColumn会自动适配对应的数据类型。
2. 检查并修复迁移脚本
如果已经生成过迁移文件,打开对应的迁移代码,确认DefinitieBehandelaar表的Id字段是否包含MySql:ValueGenerationStrategy注解。若缺失,手动补充:
migrationBuilder.CreateTable( name: "DefinitieBehandelaar", columns: table => new { Id = table.Column<int>(type: "int", nullable: false) .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), // 其他派生类专属字段... }, constraints: table => { table.PrimaryKey("PK_DefinitieBehandelaar", x => x.Id); });
之后重新执行迁移:使用Package Manager Console执行Update-Database,或者用CLI执行dotnet ef database update。
3. 确认基类Id的基础配置
基类DatabaseObject的Id只需标记为主键即可,无需额外配置自增逻辑(留给派生类处理):
public abstract class DatabaseObject { public int Id { get; set; } // 其他基类共享属性 }
4. 排查驱动版本兼容性
确保你使用的MySQL EF Core驱动(官方MySql.EntityFrameworkCore或Pomelo的Pomelo.EntityFrameworkCore.MySql)是支持.NET 8的稳定版本。旧版本驱动对TPC模式的自增列支持可能存在缺陷,升级到最新版可避免此类问题。
验证方式
迁移完成后,登录MySQL数据库执行以下命令查看表结构:
DESCRIBE DefinitieBehandelaar;
只要Id字段的Extra列显示auto_increment,再尝试添加DefinitieBehandelaar实体并调用SaveChanges即可正常工作。
内容的提问来源于stack exchange,提问作者Ldds

