EFCore 5 TPT继承场景下Credentials实体对应CLR类型无法实例化报错
问题根因
这个错误的核心原因是你使用了EF Core的表 per 类型(TPT)继承策略,但没有正确配置抽象父类Credentials的映射规则:你注释了Credentials实体的ToTable配置,EF Core无法为抽象的父类找到对应的存储映射,同时你又给两个子类单独配置了独立表,导致继承链的映射不完整。
修复方案
方案1:继续使用TPT继承策略(拆分多张表存储)
你只需要取消OnModelCreating方法中Credentials实体的配置注释即可,EF Core 5的TPT要求继承链上所有层级的实体都要配置对应的表,父类表存储公共属性,子类表存储各自特有的属性,通过主键关联父表:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Organization>(entity => { entity.ToTable(TableConsts.Organizations); entity.HasKey(x => x.Id); entity.HasMany(x => x.Users) .WithOne(x => x.Organization) .OnDelete(DeleteBehavior.ClientSetNull); // 可以放开下面的关联配置,也可以靠EF默认约定生效 entity.HasOne(x => x.BusinessCentralCredentials) .WithOne() .OnDelete(DeleteBehavior.ClientSetNull); }); // 取消这部分的注释,为抽象父类配置公共字段存储表 modelBuilder.Entity<Credentials>(entity => { entity.ToTable(TableConsts.BusinessCentralCredentials); entity.HasKey(x => x.Id); entity.HasOne(x => x.Type) .WithOne() .OnDelete(DeleteBehavior.ClientSetNull); }); modelBuilder.Entity<ClientCredentials>().ToTable(TableConsts.BusinessCentralClientCredentials); modelBuilder.Entity<AccessKeyCredentials>().ToTable(TableConsts.BusinessCentralAccessKeyCredentials); // 其余原有配置保持不变 }
修改完成后删除之前生成的错误迁移,重新执行Add-Migration和Update-Database命令生成新的迁移并更新数据库即可。
方案2:改用TPH(单表存储整个继承链)策略
如果你的业务不需要把不同类型的凭据拆分成多张表,可以直接删除两个子类的ToTable配置,EF Core会自动使用TPH策略,在Credentials表中新增Discriminator字段区分凭据类型,配置更简单,查询性能也更高:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 其余原有配置不变 // 删除下面两行子类的独立表配置即可 // modelBuilder.Entity<ClientCredentials>().ToTable(TableConsts.BusinessCentralClientCredentials); // modelBuilder.Entity<AccessKeyCredentials>().ToTable(TableConsts.BusinessCentralAccessKeyCredentials); }
内容的提问来源于stack exchange,提问作者Andrii Diachenko
相关产品推荐
相关产品推荐

