.NET Core 6中查找表记录删除失效问题排查求助
问题分析与解决方案
代码中的核心问题
- 错误的SaveChanges时机:你把
await db.SaveChangesAsync()放在了内层循环里,每次循环都会触发一次数据库提交,不仅效率极低,还可能导致部分删除操作未完成就提交,甚至引发上下文状态异常。 - 上下文实例不统一:
postSavedRisk来自_riskService的上下文,而删除操作使用了全新的ApplicationDbContext实例。两个上下文相互独立,数据库中的记录被删除后,原上下文里的postSavedRisk.AssignedTo集合不会自动更新,导致你误以为删除操作没生效。 - 嵌套循环冗余:通过嵌套循环匹配用户ID的方式效率低下,直接通过查询条件筛选要删除的记录更简洁高效。
修正后的代码
var postSavedRisk = _riskService.Queryable().Include(c => c.AssignedTo).FirstOrDefault(w => w.Id == riskitem.Id); if (postSavedRisk == null) return; List<User> usersToRemove = postSavedRisk.AssignedTo.Where(c => userNamesToRemove.Contains(c.UserName)).ToList(); if (!usersToRemove.Any()) return; using (var db = new ApplicationDbContext()) { // 直接筛选出需要删除的关联记录 var recordsToRemove = db.RiskItemUser .Where(w => w.RiskItemId == riskitem.Id && usersToRemove.Select(u => u.Id).Contains(w.UserId)) .ToList(); db.RiskItemUser.RemoveRange(recordsToRemove); await db.SaveChangesAsync().ConfigureAwait(false); // 同步原上下文的集合(可选,根据业务需求更新内存对象) foreach (var user in usersToRemove) { postSavedRisk.AssignedTo.Remove(user); } }
优化补充(上下文复用)
如果_riskService使用的是依赖注入的上下文实例,可以直接复用该上下文,避免新建实例导致的内存对象不同步问题:
var postSavedRisk = _riskService.Queryable().Include(c => c.AssignedTo).FirstOrDefault(w => w.Id == riskitem.Id); if (postSavedRisk == null) return; List<User> usersToRemove = postSavedRisk.AssignedTo.Where(c => userNamesToRemove.Contains(c.UserName)).ToList(); if (!usersToRemove.Any()) return; // 假设_riskService可直接访问上下文(例如通过暴露属性或注入) var recordsToRemove = _riskService.DbContext.RiskItemUser .Where(w => w.RiskItemId == riskitem.Id && usersToRemove.Select(u => u.Id).Contains(w.UserId)) .ToList(); _riskService.DbContext.RiskItemUser.RemoveRange(recordsToRemove); await _riskService.DbContext.SaveChangesAsync().ConfigureAwait(false); // 此时postSavedRisk.AssignedTo会自动同步,因为上下文跟踪了实体变化
内容的提问来源于stack exchange,提问作者eia92
相关产品推荐
相关产品推荐

