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

.NET 6迁移时Dynamic LINQ报“Nullable object must have a value”错误求助

.NET 6迁移后Dynamic LINQ左连接查询抛出Nullable对象必须有值异常

原.NET Core 3.1可运行代码

query = query.GroupJoin(ParsingConfig.DefaultEFCore21,
                        detailObject,
                        "new { it.ExternalDataId2.Value AS I0}",
                        "new { Id AS I0}",
                        "new (outer AS A, inner AS B)");

query = query.SelectMany("B.DefaultIfEmpty()",
                         "new { source.A.Id AS Id,source.A.ExternalDataId2 AS ExternalDataId2,detail.Title AS ExternalData2Ref_Title,detail.Id AS ExternalData2Ref_Id}",
                         "source",
                         "detail");

query.ToDynamicListAsync();

迁移至.NET 6后的错误

异常提示:

Nullable object must have a value.

完整异常堆栈:

Message: 
Test method FrameworkTests.DataLayer.FindTests.FindValueExternal threw exception: 
NTSFramework.DataLayer.DataLayerException: Errore generico di repository Nullable object must have a value.
 ---> System.InvalidOperationException: Nullable object must have a value.

  Stack Trace: 
lambda_method559(Closure , QueryContext , DbDataReader , ResultContext , SingleQueryResultCoordinator )
AsyncEnumerator.MoveNextAsync()
DynamicEnumerableAsyncExtensions.ToListAsync[T](IEnumerable source, CancellationToken cancellationToken)
DynamicEnumerableAsyncExtensions.ToListAsync[T](IEnumerable source, CancellationToken cancellationToken)
BaseDataLayer.FindValuesAsync[TModel](FindValuesOptions findOptions) line 866

注:通过SQL Profiler可见查询已执行,移除ParsingConfig无法解决问题。

尝试过的修改(可运行但无法得到所需结果)

query = query.SelectMany("B.DefaultIfEmpty()",
                         "new { source.A.Id AS Id,source.A.ExternalDataId2 AS ExternalDataId2,detail As ExternalData2Ref}",
                         "source",
                         "detail");

解决方案

问题原因

.NET 6对Nullable类型的检查和EF Core的结果映射逻辑更严格。由于使用DefaultIfEmpty()实现左连接,当detail(即B表无匹配数据)为null时,直接访问detail.Title或detail.Id会触发异常——如果这些属性是非Nullable值类型(如int),EF Core 6不允许将null映射到非Nullable字段,而.NET Core 3.1可能默认忽略了这个检查。

修改后的代码

在SelectMany的投影表达式中,为detail的属性添加空值判断:

query = query.SelectMany("B.DefaultIfEmpty()",
                         "new { source.A.Id AS Id,source.A.ExternalDataId2 AS ExternalDataId2,detail == null ? null : detail.Title AS ExternalData2Ref_Title,detail == null ? null : detail.Id AS ExternalData2Ref_Id}",
                         "source",
                         "detail");

说明

  • 通过detail == null ? null : detail.XXX的三元判断,确保当detail为null时返回null,而非强制访问非Nullable属性。
  • 如果detail.Id是值类型(如int),需要确保目标模型中对应的ExternalData2Ref_Id字段是可空类型(如int?),否则仍会出现映射错误。

内容的提问来源于stack exchange,提问作者Paolo Crociati

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 11:05:34