ASP.NET Core 2自定义Identity主键为long时UserStore报错问题
这个错误我之前踩过坑,本质是泛型类型约束不匹配导致的——默认的UserStore<TUser>是给string主键的IdentityUser<string>设计的,当你把主键改成long后,你的ApplicationUser继承的是IdentityUser<long>,自然就不符合默认UserStore的泛型约束了,所以编译器报错。
下面是一步步的解决办法:
1. 确保ApplicationUser继承正确的IdentityUser
把你的ApplicationUser类改成继承带long主键的IdentityUser<long>,而不是默认的无参数IdentityUser(后者默认用string主键):
public class ApplicationUser : IdentityUser<long> { // 这里放你的自定义用户属性,比如FullName之类的 }
2. 更新DbContext的继承关系
你的ApplicationDbContext需要继承针对long主键的IdentityDbContext泛型版本,指定用户、角色和主键类型:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole<long>, long> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } // 其他DbSet... }
如果不需要自定义角色,也可以保持这个写法,确保主键类型统一为long即可。
3. 修正Identity服务注册(Program.cs/Startup.cs)
在配置服务的时候,要明确指定用户、角色和主键类型,让DI容器注册正确的Store实现:
// Program.cs 示例 builder.Services.AddIdentity<ApplicationUser, IdentityRole<long>>() .AddEntityFrameworkStores<ApplicationDbContext, long>() .AddDefaultTokenProviders();
如果用的是AddDefaultIdentity,也要确保它的泛型参数是ApplicationUser,后续的AddEntityFrameworkStores能匹配你的DbContext类型。
4. 修正种子类中的UserStore实例化
原来的new UserStore<ApplicationUser>(context)之所以报错,是因为这个构造函数对应的泛型约束是TUser : IdentityUser<string>,你的ApplicationUser不符合。你需要使用带完整泛型参数的UserStore构造函数:
// 替换原来的代码 var userStore = new UserStore<ApplicationUser, IdentityRole<long>, ApplicationDbContext, long>(context);
这样就明确告诉编译器,我们的用户类型是ApplicationUser,角色类型是IdentityRole<long>,DbContext是ApplicationDbContext,主键类型是long,完全匹配泛型约束。
做完这些步骤后,编译器的波浪线应该就消失了,种子类也能正常使用UserStore来创建用户了。
内容的提问来源于stack exchange,提问作者greedyLump




