EF Core 3.0 Preview4中继承IdentityUser的Owned Type异常问题
EF Core 3.0 Preview4: Owned Type Creates Separate Table Instead of Embedding for IdentityUser-Derived Class
我之前也碰到过一模一样的问题,在EF Core 3.0 Preview4里,继承自IdentityUser<TKey>的实体配置Owned Type时,总会默认生成单独表——这主要是因为Identity框架在EF Core中的默认模型配置优先级更高,直接覆盖了Owned Type的嵌入行为。
要解决这个问题,你需要在OnModelCreating里显式配置Owned Type的属性映射到主表的列,而不是只简单调用OwnsOne。具体操作如下:
解决方案代码示例
public class ApplicationDbContext : IdentityDbContext<User, IdentityRole<Guid>, Guid> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { // 先执行Identity的默认模型配置 base.OnModelCreating(modelBuilder); // 显式配置SMSCodeInfo作为User的Owned Type,并映射到AspNetUsers表的列 modelBuilder.Entity<User>() .OwnsOne(u => u.SMSCodeInfo, ownedBuilder => { // 为Owned Type的属性指定主表中的列名 ownedBuilder.Property(s => s.Code).HasColumnName("SMSCode"); ownedBuilder.Property(s => s.Expiration).HasColumnName("SMSCodeExpiration"); // 可选:添加业务所需的约束,比如非空 ownedBuilder.Property(s => s.Code).IsRequired(); ownedBuilder.Property(s => s.Expiration).IsRequired(); }); } }
为什么这样能解决问题?
在EF Core 3.0的早期预览版本中,Identity的默认配置没有正确处理继承实体的Owned Type嵌入逻辑,导致EF Core误把SMSCodeInfo当成了需要单独存储的关联实体。通过显式指定每个Owned属性对应的主表列名,我们强制EF Core将这些属性嵌入到AspNetUsers表中,而非生成新表。
另外,仅使用[Owned]特性可能无效,因为Identity的配置会覆盖这个特性的行为,所以必须通过Fluent API来显式配置。
验证效果
重新生成迁移并更新数据库后,你会看到AspNetUsers表新增了SMSCode和SMSCodeExpiration两列,不会再生成AspNetUsers1这个多余的表——和你项目中其他非Identity继承类的Owned Type行为完全一致。
内容的提问来源于stack exchange,提问作者Dmitriy
相关产品推荐
相关产品推荐

