ASP.NET Core 6 Identity调用AddToRoleAsync触发MySQL外键约束异常
在ASP.NET Core 6中使用Identity系统,可正常将角色添加至AspNetRoles表、用户添加至AspNetUsers表,但调用AddToRoleAsync方法时触发外键约束异常。
代码示例
// Create Member Role result = await roleManager.CreateAsync(new IdentityRole("Member")); if (!result.Succeeded) return 2; // log an error message here // Create Member User newid = Guid.NewGuid().ToString(); var memberUser = new ApplicationUser { Id = newid, UserName = "mem@a.ca", Email = "mem@a.ca", Fname = "The", Lname = "Member", EmailConfirmed = true }; result = await userManager.CreateAsync(memberUser, "Password1!"); if (!result.Succeeded) return 3; // log an error message here // Assign user to Member role (FAILS) result = await userManager.AddToRoleAsync(memberUser, "Member"); if (!result.Succeeded) return 4; // log an error message here <--- Goes here.
触发的异常
MySqlException: Cannot add or update a child row: a foreign key constraint fails (
dbname.aspnetuserroles, CONSTRAINTFK_AspNetUserRoles_AspNetUsers_UserIdFOREIGN KEY (UserId) REFERENCESaspnetusers(Id) ON DELETE CASCADE)
解决建议
重新获取数据库中的用户实例:调用
CreateAsync后,当前的memberUser对象可能脱离了EF Core上下文的跟踪状态,导致添加角色时无法正确匹配数据库中的用户记录。解决方式是创建用户后,通过userManager重新查询用户实例:// 创建用户后新增这段代码 var existingUser = await userManager.FindByIdAsync(newid); if (existingUser == null) return 5; // 处理用户不存在的情况 // 使用重新获取的用户实例添加角色 result = await userManager.AddToRoleAsync(existingUser, "Member");检查数据库大小写匹配:MySQL默认可能对表名、列名区分大小写,确认
AspNetUsers表的Id列值与aspnetuserroles表中外键引用的UserId值大小写完全一致,同时检查数据库的大小写敏感配置。验证Identity上下文配置:确保
ApplicationDbContext正确继承IdentityDbContext<ApplicationUser>,且用户和角色的主键类型(此处为string/Guid)与数据库表中对应列的类型完全匹配。
内容的提问来源于stack exchange,提问作者Jems Chaudhary

