如何在foreach循环中检查空值?解决迭代空引用异常
空引用异常排查与修复方案
问题根源分析
你的代码存在多处未处理null值的场景,以及逻辑错误,直接导致空引用异常:
- 筛选逻辑错误:用
OrderByDescending(r => r.Status.Equals("New"))只是按是否为"New"排序,并没有筛选出状态为"New"的记录,后续循环会处理大量无关数据。 - 未处理null结果:
FirstOrDefault()可能返回null,但你直接访问其属性(比如departmentId.DepartmentId、ProcessStepLog.FirstOrDefault().ProcessStepName),一旦返回null就触发空引用。 - 重复数据库查询:循环内重复调用
_userManager.GetUserAsync(User)和两次查询ProcessStepLog,既浪费性能也增加出错概率。
修复后的代码
public async Task<IActionResult> NewRequisitionsEntryList() { // 1. 先筛选出状态为"New"的申请,再按创建时间倒序 var newReqList = _context.Requisition .Where(r => r.Status.Equals("New")) .OrderByDescending(r => r.DateCreated) .ToList(); // 2. 将用户信息查询移到循环外,避免重复查询 UserInformation identityUser = await _userManager.GetUserAsync(User); if (identityUser == null || string.IsNullOrEmpty(identityUser.Department)) { ViewData["requistionsNew"] = new List<NewRequistionModel>(); return View(newReqList); } // 3. 查询用户部门,添加null检查 var department = _context.Department .FirstOrDefault(x => x.DepartmentName == identityUser.Department); if (department == null) { ViewData["requistionsNew"] = new List<NewRequistionModel>(); return View(newReqList); } var userDepartmentId = department.DepartmentId; foreach (var req in newReqList) { // 4. 部门不匹配直接跳过 if (userDepartmentId != req.DepartmentId) { continue; } // 5. 查询流程日志,先获取对象再判断,避免重复查询 var processStepLog = _context.ProcessStepLog .FirstOrDefault(d => d.RequistionId == req.RequisitionId); if (processStepLog != null && processStepLog.ProcessStepName == "New") { requistionsNew.Add(new NewRequistionModel() { RequistionNo = req.RequisitionNo, RequisitionTitle = req.RequisitionTitle, DateCreated = req.DateCreated, ProcessStepName = processStepLog.ProcessStepName, RequestedBy = req.QueriesEmail, }); } } ViewData["requistionsNew"] = requistionsNew; return View(newReqList); }
关键改进点
- 精准筛选:用
Where过滤出状态为"New"的记录,减少循环处理的数据量。 - 提前null检查:对
identityUser、department、processStepLog都添加null判断,从根源避免空引用。 - 减少重复查询:将用户和部门查询移到循环外,单条流程日志只查询一次。
- 逻辑优化:部门不匹配直接跳过迭代,减少不必要的判断逻辑。
内容的提问来源于stack exchange,提问作者Zidane
相关产品推荐
相关产品推荐

