扩展IdentityUser并设UserName/Email为必填后FindByEmailAsync返回空字段问题
问题原因及解决方案
核心问题1:DbContext继承未指定自定义用户类型
你的ApplicationDbContext继承的是默认IdentityDbContext(等价于IdentityDbContext<IdentityUser>),而非针对ExtendedIdentityUser的泛型版本。这导致Identity框架内部仍使用默认的IdentityUser类型处理数据,无法正确映射自定义的ExtendedIdentityUser属性,进而查询时UserName和Email字段无法被正确赋值。
核心问题2:不必要的属性重写
你重写了UserName和Email属性并设置默认值string.Empty,干扰了EF Core的属性映射逻辑——基类IdentityUser已对这两个属性有完整的映射配置,重写后破坏了原有映射关联,导致查询时数据库值无法正确绑定到实体属性。
具体修复步骤
1. 修正ApplicationDbContext的继承
将DbContext改为继承IdentityDbContext<ExtendedIdentityUser>,并移除多余的DbSet<ExtendedIdentityUser>(泛型版本的IdentityDbContext已内置对应的Users集合):
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : IdentityDbContext<ExtendedIdentityUser>(options) { // 移除该行:public DbSet<ExtendedIdentityUser> ExtendedIdentityUsers { get; set; } // 其他表 protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.ApplyConfiguration(new ExtendedIdentityUserMap()); // 其他映射 } }
2. 移除ExtendedIdentityUser中对UserName和Email的重写
保留基类属性,仅通过Fluent API配置必填规则即可:
public class ExtendedIdentityUser : IdentityUser { public DateTime RegistrationDate { get; set; } }
3. 保留原有的映射配置(无需修改)
你的ExtendedIdentityUserMap配置是正确的,修正上述两点后,它会正确作用于基类继承来的UserName和Email属性:
public class ExtendedIdentityUserMap : IEntityTypeConfiguration<ExtendedIdentityUser> { public void Configure(EntityTypeBuilder<ExtendedIdentityUser> builder) { // Properties builder.Property(u => u.UserName).HasColumnName("UserName").IsRequired(); builder.Property(u => u.Email).HasColumnName("Email").IsRequired(); builder.Property(u => u.RegistrationDate).IsRequired(); // Default values builder.Property(u => u.RegistrationDate).HasDefaultValueSql("GETDATE()"); } }
验证修复
完成修改后,重新生成并应用迁移(若需),再调用userManager.FindByEmailAsync即可正常获取包含UserName和Email的完整用户对象。
内容的提问来源于stack exchange,提问作者1_bug
相关产品推荐
相关产品推荐

