ASP.NET Core IdentityDbContext如何将内置布尔字段设置为非必填
问题本质
你遇到的报错是EF Core的基础规则导致的:bool、int这类值类型本身是非空类型,只有可空值类型(后缀带?,比如bool?、int?)或者引用类型才能被标记为可选(IsRequired(false))。
另外你提到的这几个字段都继承自IdentityUser基类,ASP.NET Core Identity的内置逻辑本身依赖这几个字段为非空状态,强行改可空大概率会破坏原有功能。
推荐解决方案(无副作用)
不需要改属性可空,只要给字段配置数据库默认值即可,插入数据时不需要主动赋值就能自动填充默认值,完全达到「非必填」的使用效果:
在你的DDMDbContext的OnModelCreating方法中追加ApplicationUser的配置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // 原有ApplicationUserRole配置保留 modelBuilder.Entity<ApplicationUserRole>(userRole => { userRole.HasKey(ur => new { ur.UserId, ur.RoleId }); userRole.HasOne(ur => ur.Role) .WithMany(r => r.UserRoles) .HasForeignKey(ur => ur.RoleId) .IsRequired(); userRole.HasOne(ur => ur.User) .WithMany(r => r.UserRoles) .HasForeignKey(ur => ur.UserId) .IsRequired(); }); // 新增ApplicationUser字段默认值配置 modelBuilder.Entity<ApplicationUser>(entity => { entity.Property(m => m.EmailConfirmed).HasDefaultValue(false); entity.Property(m => m.PhoneNumberConfirmed).HasDefaultValue(false); entity.Property(m => m.TwoFactorEnabled).HasDefaultValue(false); entity.Property(m => m.LockoutEnabled).HasDefaultValue(true); entity.Property(m => m.AccessFailedCount).HasDefaultValue(0); }); }
配置完成后重新生成迁移并更新数据库即可,所有字段仍然是非空,但插入时无需手动赋值,数据库会自动填充你设置的默认值。
不推荐解决方案(强行改可空)
如果你确实需要数据库字段为可空状态(会破坏Identity内置功能,仅适合完全自定义用户逻辑的场景),可以在ApplicationUser类中用new关键字重写基类属性为可空类型:
public class ApplicationUser : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } public ICollection<ApplicationUserRole> UserRoles { get; set; } // 重写基类属性为可空值类型 public new bool? EmailConfirmed { get; set; } public new bool? PhoneNumberConfirmed { get; set; } public new bool? TwoFactorEnabled { get; set; } public new bool? LockoutEnabled { get; set; } public new int? AccessFailedCount { get; set; } }
修改后再配置IsRequired(false)就不会报错,但后续使用Identity内置的UserManager、SignInManager等服务时可能出现空引用异常,需要自行适配所有逻辑。
内容的提问来源于stack exchange,提问作者Olugbenga
相关产品推荐
相关产品推荐

