You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 3.1迁移至.NET 7时出现“Nullable object must have a value”异常求助

.NET Core 3.1迁移.NET7 EF Core "Nullable object must have a value" 异常解决方案

异常原因

EF Core从.NET 5开始调整了左连接(DefaultIfEmpty())中非可空值类型的处理逻辑:当关联表无匹配数据时,不再自动为实体的非可空值类型属性(如int、DateTime)填充默认值,而是尝试将null赋值给非可空属性,触发"Nullable object must have a value"异常。而.NET Core 3.1中EF Core会自动为这类属性填充默认值(如int填0、DateTime填DateTime.MinValue)。

解决方案

1. 全局配置恢复旧行为(推荐,适配大量遗留代码)

在DbContext的OnConfiguring方法中添加UseRelationalNulls(false)配置,强制EF Core回到.NET Core 3.1的null处理逻辑:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer("你的数据库连接字符串") // 根据实际数据库替换驱动,比如UseInMemoryDatabase
        .UseRelationalNulls(false); // 关键配置,恢复自动填充默认值的行为
}

说明:UseRelationalNulls是EF Core 3.0引入的API,设置为false时,EF Core会将数据库返回的null值转换为对应CLR类型的默认值,避免赋值非可空属性时抛出异常。

2. 局部查询调整(适合少量代码场景)

若不想全局修改,可在查询中手动为可能为null的实体指定默认对象,但此方式需逐个修改查询,仅适合少量场景:

var query = from p in dbContext.Products.Where(p => dto.Ids.Contains(p.Id))
            from c in dbContext.Categorys.Where(c => c.Id == p.CategoryId).DefaultIfEmpty()
            from wh in dbContext.Warehouses.Where(wh => wh.Id == p.WarehouseId).DefaultIfEmpty()
            select new 
            {
                Product = p,
                Category = c ?? new Category { Id = 0, Name = string.Empty },
                Warehouse = wh ?? new Warehouse { Id = 0, Location = string.Empty }
            };

补充说明

  • 全局配置UseRelationalNulls(false)会作用于整个DbContext的所有查询,完全模拟.NET Core 3.1的行为,是处理大量遗留代码的最优方案。
  • 若后续计划逐步优化代码,可先通过全局配置过渡,再逐步将实体类的非可空值类型改为可空类型(如int→int?),同时调整业务逻辑处理null场景。

内容的提问来源于stack exchange,提问作者Dan Van

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 07:37:30