ASP.NET Core 6中LINQ查询因空引用崩溃问题排查
问题原因分析
崩溃的核心原因是**CaseEntity中的CoordinatorName是可空字符串类型(string?),数据库中存在该字段为null的记录**。当LINQ查询执行it.CoordinatorName.Contains(...)或it.CoordinatorName.ToLower()时,若某条记录的CoordinatorName为null,调用字符串方法就会触发空引用异常——哪怕请求参数里的CoordinatorName有有效值,只要数据集里存在null值的记录,就会触发崩溃。
解决方案
针对这个问题,有几种可靠的修复方式,按推荐优先级排序:
1. 数据库层面提前过滤(性能最优)
不要先把全表数据加载到内存再过滤,直接在EF Core查询中加入null判断,既避免空引用,又提升查询性能:
var targetCoordinator = request.caseDtos.CoordinatorName; var data = await _repository.Table .Where(it => it.CoordinatorName != null && it.CoordinatorName.Contains(targetCoordinator)) .ToListAsync();
如果需要忽略大小写匹配:
var targetCoordinatorLower = request.caseDtos.CoordinatorName.ToLower(); var data = await _repository.Table .Where(it => it.CoordinatorName != null && it.CoordinatorName.ToLower().Contains(targetCoordinatorLower)) .ToListAsync();
2. 内存过滤时处理null值
如果必须先加载全表数据到内存,可通过空传播运算符(?.)或显式null判断避免异常:
方式一:显式null判断
data = data.Where(it => it.CoordinatorName != null && it.CoordinatorName.Contains(request.caseDtos.CoordinatorName)).ToList();
方式二:空传播+布尔判断
利用空传播运算符返回可空布尔值,再判断是否为true:
data = data.Where(it => it.CoordinatorName?.Contains(request.caseDtos.CoordinatorName) == true).ToList();
忽略大小写的版本:
var targetLower = request.caseDtos.CoordinatorName.ToLower(); data = data.Where(it => it.CoordinatorName?.ToLower().Contains(targetLower) == true).ToList();
额外说明
你测试的那段coordinatorName.Where(it => it.Contains(...))能正常运行,大概率是因为测试数据集里的CoordinatorName没有null值,但生产环境中存在这类数据,才触发了异常。
内容的提问来源于stack exchange,提问作者GettingStarted
相关产品推荐
相关产品推荐

