IdentityUser.Update主键重复报错修复:不修改用户名更新用户属性
问题描述
报错信息:IdentityUser.Update(user) 存在另一个同类型实体拥有相同主键值。
提交编辑请求时,修改UserName无报错,但不修改用户名时触发该错误,核心代码如下:
[HttpPost] public ActionResult Edit(ApplicationUser user, string password) { if(password.IsEmpty() == false) { user.PasswordHash = userManager.PasswordHasher.HashPassword(password); } user.Status = Enums.DataStatus.Updated; var result =userManager.Update(user); // 报错位置! return RedirectToAction("EmployeeList"); }
问题原因
本质是EF实体跟踪冲突:当不修改UserName时,ModelBinding生成的user是全新实例,但主键与数据库中已存在的用户一致。此时DbContext可能已经通过之前的操作(比如登录用户查询、页面加载时的用户数据查询)跟踪了同主键的ApplicationUser实体,EF不允许上下文同时跟踪两个主键相同的同类型实体,因此调用Update时触发错误。
而修改UserName时,EF内部逻辑因属性变化未触发跟踪冲突,所以能正常执行。
解决方案
方案1:先获取跟踪实体再更新属性(推荐)
这种方式明确控制更新字段,完全避免跟踪冲突,也是最稳妥的做法:
[HttpPost] public async Task<ActionResult> Edit(ApplicationUser inputUser, string password) { // 从UserManager获取数据库中当前的用户实体(该实体已被上下文跟踪) var dbUser = await userManager.FindByIdAsync(inputUser.Id.ToString()); if (dbUser == null) { return NotFound(); } // 按需更新属性 if (!string.IsNullOrEmpty(password)) { dbUser.PasswordHash = userManager.PasswordHasher.HashPassword(password); } dbUser.Status = Enums.DataStatus.Updated; // 如需修改其他属性,比如Email、昵称等,直接在这里赋值 // dbUser.Email = inputUser.Email; // 更新已跟踪的实体 var result = await userManager.UpdateAsync(dbUser); return RedirectToAction("EmployeeList"); }
方案2:手动处理实体状态(适合简单更新场景)
如果不想提前查询实体,可以手动处理实体的跟踪状态,但要注意避免覆盖不需要更新的字段:
[HttpPost] public ActionResult Edit(ApplicationUser user, string password) { if(!string.IsNullOrEmpty(password)) { user.PasswordHash = userManager.PasswordHasher.HashPassword(password); } user.Status = Enums.DataStatus.Updated; // 检查上下文是否已跟踪该实体 var trackedUser = userManager.Users.Local.FirstOrDefault(u => u.Id == user.Id); if (trackedUser != null) { // 将传入的属性值复制到已跟踪的实体上 userManager.Context.Entry(trackedUser).CurrentValues.SetValues(user); } else { // 未跟踪则附加实体并标记为修改状态 userManager.Context.Attach(user); userManager.Context.Entry(user).State = EntityState.Modified; } var result = userManager.Update(user); return RedirectToAction("EmployeeList"); }
内容的提问来源于stack exchange,提问作者ayddnuh
相关产品推荐
相关产品推荐

