EF Core 6报错‘Nullable object must have a value’原因排查
首先你的代码存在一个明显的逻辑错误:查询起点是_context.Fee(DbSet<Fee>类型),但使用的expression是针对TimeSlot类型的表达式树,这种类型不匹配会导致EF Core在解析表达式时出现异常行为——移除x.Status == 1时可能侥幸绕过了nullable属性的访问,但加入该条件后,问题被触发。
具体和x.Status == 1关联的原因如下:
可空属性的强制访问
检查你的Fee实体类,Status属性大概率被定义为可空类型(int?)。当你添加x.Status == 1条件时,EF Core在处理表达式时,若遇到Status为null的记录(哪怕测试数据里都是1,实际场景或关联查询中可能出现null值),会尝试调用x.Status.Value来和1做比较,而null的可空类型访问Value属性就会直接抛出“Nullable object must have a value”错误。null导航属性的集合过滤触发
第一条Fee数据的HospitalId是NULL,对应的Hospital导航属性为null。当表达式中访问e.Hospital.Fee并添加过滤条件时,EF Core需要对这个潜在的null集合进行处理:移除x.Status ==1时,EF Core可能生成的SQL没有严格执行过滤逻辑,或者在内存中跳过了null导航属性的处理;但加入该条件后,必须对集合进行过滤操作,此时访问null导航属性的集合会间接触发nullable值的强制访问错误。表达式解析的异常放大
原本查询起点和表达式类型不匹配的问题,在没有Status过滤时,EF Core的表达式解析器可能没有触发到nullable属性的校验;但添加条件后,表达式复杂度提升,解析器需要处理更多属性逻辑,类型不匹配导致的异常被放大,最终暴露了nullable属性的访问错误。
修复建议
首先修正查询起点,应该从TimeSlot集合出发(因为你的表达式是针对TimeSlot的),同时调整过滤逻辑:
var data = _context.TimeSlot .Where(ts => ts.Hospital != null && ts.Hospital.Fee.Any(f => f.DoctorId == "a5bf5fa0")) .Select(expression) .AsNoTracking() .ToPaginatedListAsync(request.PageNumber, request.PageSize);
另外,建议将Fee实体的Status属性改为非可空类型(如果业务上Status不允许为null),或者在条件中先判断x.Status.HasValue:
Fees = e.Hospital.Fee.Where(x => x.HospitalId != null && x.Status.HasValue && x.Status == 1) .Select(...)
内容的提问来源于stack exchange,提问作者Randy

