保存新用户时出现‘IdentityUserLogin<string>需定义主键’错误
解决IdentityUserLogin主键缺失错误的方案
问题根源
使用Database-First模式时,Scaffold-DbContext工具生成的上下文没有正确继承Identity的配置逻辑,就算添加了base.OnModelCreating(builder),也可能因为自动生成的Identity实体模型与框架内置定义冲突,导致主键配置失效。
分步解决
1. 修正DbContext继承关系
将你的DbContext改为继承IdentityDbContext<IdentityUser>(如果用了自定义用户类,替换成对应的类),而非普通的DbContext:
public class AppDbContext : IdentityDbContext<IdentityUser> { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } // 这里放置你的业务表DbSet public DbSet<Order> Orders { get; set; } protected override void OnModelCreating(ModelBuilder builder) { // 必须优先调用Identity的基础配置 base.OnModelCreating(builder); // 再添加业务模型的配置(如果Scaffold生成了相关代码) } }
2. 删除自动生成的Identity实体
如果Scaffold-DbContext工具生成了IdentityUserLogin、IdentityUserRole、IdentityUserClaim这类文件,直接删除!Identity框架已经自带这些实体的默认定义,手动生成的文件会和内置配置冲突,导致主键无法被正确识别。
3. 重新生成上下文(按需操作)
如果之前的Scaffold命令包含了AspNet开头的Identity系统表,重新运行时只指定你自己创建的业务表:
Scaffold-DbContext "你的数据库连接字符串" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables Orders,Products
这样就不会生成与Identity冲突的实体文件了。
4. 检查Program.cs的Identity配置
确保服务注册时正确关联你的DbContext:
builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = false) .AddEntityFrameworkStores<AppDbContext>();
题外话:其实不用转Database-First
你当初切换模式是因为不知道怎么给业务模型和AspNetUsers表加外键,Code-First完全可以实现:
比如在业务模型里添加UserId字段,用数据注解或Fluent API关联:
public class Order { public int Id { get; set; } public string UserId { get; set; } [ForeignKey(nameof(UserId))] public IdentityUser User { get; set; } }
或者在OnModelCreating中配置:
builder.Entity<Order>() .HasOne(o => o.User) .WithMany() .HasForeignKey(o => o.UserId);
用Code-First维护更省心,不用来回切换模式。
内容的提问来源于stack exchange,提问作者S. Gunel
相关产品推荐
相关产品推荐

