.NET 5升级至.NET 6后LINQ查询抛出SqlNullValueException异常
问题根因
- 该问题由EF Core 6 RC版本的两个变更共同导致:第一是针对TPH(表 per 层次结构)继承体系的查询生成逻辑存在bug,当查询同时包含关联Include、基类类型Select投影时,会错误生成不相关子类的独有字段查询逻辑,导致返回结果中出现多余的null值;第二是EF Core 6默认收紧了非可空属性的空值校验规则,若查询返回字段存在null值,但映射的实体属性声明为非可空类型,会直接抛出
SqlNullValueException,而.NET 5配套的EF Core 5会静默为该属性填充默认值,不会抛出异常。 - 你当前使用的RC2为预览版本,对应bug未被修复,因此原有正常运行的代码会触发异常。
解决方案
临时兼容方案(无需升级依赖版本)
- 关闭EF Core的非可空属性空值校验,在DbContext的
OnConfiguring方法中添加如下配置:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNullabilityChecks(false); }
- 调整查询写法,将投影逻辑显式转换为筛选后的实际子类类型,避免EF Core错误映射基类字段:
var clients = _dbContext.AppUserAppUsers .Where(x => x.AppUserParentId == designerId && x.ChildAppUser.AppUserRole == AppUserRole.Client) .Include(x => x.ChildAppUser.Profile) .Select(x => (ClientModel)x.ChildAppUser) .AsNoTracking(); return clients.ToList();
- 重构查询逻辑,直接从子类侧发起查询,绕过多对多关联+Include+投影的组合触发场景:
var clients = _dbContext.Set<ClientModel>() .Where(c => c.ParentAppUsers.Any(p => p.AppUserParentId == designerId)) .Include(c => c.Profile) .AsNoTracking() .ToList();
永久修复方案
将所有Microsoft.EntityFrameworkCore开头的依赖包升级到6.0.0正式版及以上版本,微软已在正式版中修复了TPH场景的查询生成bug,升级后无需修改原有代码即可正常运行。
内容的提问来源于stack exchange,提问作者David Evans
相关产品推荐
相关产品推荐

