如何通过for循环遍历SQL查询结果并删除对应单条数据库数据行
代码存在的问题
- 第一层for循环边界错误:
i <= user.personList.Length会触发数组索引越界,数组索引范围是0 ~ Length-1,应改为i < user.personList.Length Where返回的IQueryable对象永远不会为null,你写的if (prozessPersonenzuordnungen == null)判断没有意义,应该判断是否存在匹配数据- 内层循环没必要通过下标遍历,
Count()每次调用都会触发一次数据库查询,放在循环条件里会严重影响性能 FindAsync需要传入主键的具体值,你传入Select返回的IQueryable对象完全不符合参数要求,当然无法生效- 每次删除都调用
SaveChangesAsync会产生大量数据库交互,性能极低
修正后的代码
[HttpPost("delUebertrag/")] public async Task<ActionResult<ProzessPersonenzuordnungen>> delRecUebertrag([FromBody] recUebertragModel user) { Guid prozessId = new Guid(user.prozessId); for (var i = 0; i < user.personList.Length; i++) { Guid personId = new Guid(user.personList[i]); // 直接查询所有符合条件的待删除实体,加载到内存中 var toDeleteList = await _context.ProzessPersonenzuordnungens .Where(p => p.ProzessId == prozessId && p.PersonId == personId) .ToListAsync(); if (!toDeleteList.Any()) { return NotFound(); } // 批量移除所有匹配实体 _context.ProzessPersonenzuordnungens.RemoveRange(toDeleteList); } // 所有删除操作完成后统一提交到数据库 await _context.SaveChangesAsync(); return Ok(); }
优化说明
- 直接用
ToListAsync一次性查询出所有符合条件的待删除实体,避免多次查询数据库,你可以直接遍历这个列表拿到每条记录的主键ProzessPersonenzuordnungId做额外处理:foreach(var item in toDeleteList) { // 此处即可获取单条记录ID var currentId = item.ProzessPersonenzuordnungId; _context.ProzessPersonenzuordnungens.Remove(item); } - 不需要额外操作的话直接用EF内置的
RemoveRange方法批量删除实体,减少代码冗余 - 所有删除操作完成后统一调用
SaveChangesAsync,大幅减少数据库交互次数 - 修正了边界错误和无效判断逻辑
内容的提问来源于stack exchange,提问作者DeChopper
相关产品推荐
相关产品推荐

