.NET Core 8 Identity模型自定义:'UserId1'列无效错误排查
解决EF Core中Identity用户访问UserRoles时的"Invalid column name 'UserId1'"错误
我在从User(对应ApplicationUser)实体访问UserRoles属性时,一直收到错误提示:Invalid column name 'UserId1'。我按照官方文档的步骤配置Identity模型,但EF始终试图生成重复列,不清楚问题出在哪。
相关代码
User类(ApplicationUser)
public class User : IdentityUser { public ICollection<IdentityUserClaim<string>> Claims { get; set; } public ICollection<IdentityUserLogin<string>> Logins { get; set; } public ICollection<IdentityUserToken<string>> Tokens { get; set; } public ICollection<UserRole> UserRoles { get; set; } }
SqlContext上下文
public class SqlContext : IdentityDbContext<User, Role, string, IdentityUserClaim<string>, UserRole, IdentityUserLogin<string>, IdentityRoleClaim<string>, IdentityUserToken<string>> { public SqlContext(DbContextOptions<SqlContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { builder.Entity<User>(b => { // Each User can have many UserClaims b.HasMany(e => e.Claims) .WithOne() .HasForeignKey(uc => uc.UserId) .IsRequired(); // Each User can have many UserLogins b.HasMany(e => e.Logins) .WithOne() .HasForeignKey(ul => ul.UserId) .IsRequired(); // Each User can have many UserTokens b.HasMany(e => e.Tokens) .WithOne() .HasForeignKey(ut => ut.UserId) .IsRequired(); // Each User can have many entries in the UserRole join table b.HasMany(e => e.UserRoles) .WithOne(e => e.User) .HasForeignKey(ur => ur.UserId) .IsRequired(); }); builder.Entity<Role>(b => { // Each Role can have many entries in the UserRole join table b.HasMany(e => e.UserRoles) .WithOne(e => e.Role) .HasForeignKey(ur => ur.RoleId) .IsRequired(); }); base.OnModelCreating(builder); } }
Program.cs配置
builder.Services.AddIdentity<User, Role>() .AddEntityFrameworkStores<SqlContext>() .AddDefaultTokenProviders() .AddClaimsPrincipalFactory<CustomClaimsPrincipalFactory>();
解决方案
问题核心是OnModelCreating中调用base.OnModelCreating(builder)的顺序错误。Identity的默认配置会自动设置导航属性和外键,手动配置后再调用基类方法,会导致EF重复建立关联,生成额外的UserId1列。
- 调整基类方法调用顺序
将base.OnModelCreating(builder)移到自定义配置代码之前,让默认配置先执行,再用自定义配置补充:
protected override void OnModelCreating(ModelBuilder builder) { // 先执行Identity默认配置 base.OnModelCreating(builder); builder.Entity<User>(b => { b.HasMany(e => e.Claims) .WithOne() .HasForeignKey(uc => uc.UserId) .IsRequired(); b.HasMany(e => e.Logins) .WithOne() .HasForeignKey(ul => ul.UserId) .IsRequired(); b.HasMany(e => e.Tokens) .WithOne() .HasForeignKey(ut => ut.UserId) .IsRequired(); b.HasMany(e => e.UserRoles) .WithOne(e => e.User) .HasForeignKey(ur => ur.UserId) .IsRequired(); }); builder.Entity<Role>(b => { b.HasMany(e => e.UserRoles) .WithOne(e => e.Role) .HasForeignKey(ur => ur.RoleId) .IsRequired(); }); }
- 确保UserRole类的完整性
确认UserRole类正确继承并包含导航属性:
public class UserRole : IdentityUserRole<string> { public virtual User User { get; set; } public virtual Role Role { get; set; } }
- 同步数据库结构
重新生成迁移并更新数据库,保证模型与数据库一致:
Add-Migration FixUserRoleForeignKey Update-Database
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

