DEBUG.WIKI
腾讯云;让你的想法跑起来;轻量服务器 · 建站 / Docker / API;查看产品 →
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS

EF Core 11 RC3 嵌套 JSON 集合保存时报 TryExpression 异常

EF Core 11 RC3 开启 EnableDetailedErrors 后,嵌套 JSON 复杂集合中的可空值类型可能触发 getter 编译异常。先限定版本和模型条件,再临时关闭这项诊断增强。

保存 JSON 数据时还没发出 SQL,就出现包含 TryExpression、值类型成员访问的 NotSupportedException;换成 ChangeTracker.Entries() 或显式 DetectChanges(),仍然报同一异常。若项目刚切到 EF Core 11 RC3,并启用了 EnableDetailedErrors(),先检查 JSON 映射是否有两层复杂集合,内层又含 DateOnly? 等可空值类型。

这一组合会在创建属性访问器时失败。它不表示数据库拒绝了 NULL,也不能靠把日期批量补成某个默认值来处理。

先把触发条件收窄

已确认的环境是 11.0.0-rc.3.26522.148,使用 .NET 11 RC3,Sqlite 和 Npgsql 提供程序都出现相同表现。模型形状类似 Blog 的 Posts 集合中,每个 Post 又有 Revisions 集合,Revision 内有 DateOnly? 属性;外层复杂集合用 ToJson() 存储。

单层集合、内层没有可空值类型,以及没有启用详细错误增强的路径,需要分别对照。单凭应用使用了 JSON,无法把其他保存异常归到这里。先保留完整异常栈,确认失败点在表达式访问器构造或编译,而不是 SQL 执行、并发检查或约束校验。

临时关闭受影响上下文的详细错误增强

EnableDetailedErrors() 会为数据访问增加诊断表达式。对符合上述条件的上下文,可以暂时移除这次调用,或在最终选项配置位置显式关闭:

optionsBuilder.EnableDetailedErrors(false);

保留原来的数据库提供程序、连接设置、模型映射和正常日志配置。若项目在多个位置配置 DbContext,核对最终生效的选项,避免后面的 EnableDetailedErrors() 又把它打开。若通过 UseInternalServiceProvider 显式复用内部服务提供程序,还要让其所有 DbContext 使用一致的详细错误选项,不能只在其中一处切换。这个调整减少的是详细错误诊断信息,不应同时关闭变更检测、取消属性映射或修改业务数据。

关闭开关后能保存,只能支持这条触发路径的判断。若异常仍在,继续依据新异常栈排查;不要反复切换诊断配置掩盖另一类模型问题。对于必须依赖详细错误信息的调试任务,可在不含该模型组合的隔离环境中继续使用,避免把临时兼容配置扩散到所有应用。

回归要覆盖保存和跟踪读取

在可回滚的测试数据上,同时检查内层日期为 NULL 和有值、内层空集合和非空集合。先执行原来会失败的变更检测,再保存,并用新上下文重新查询,比较集合层次、元素数量和日期值。只看到 SaveChanges() 没抛异常,还不足以证明 JSON 内容完整。

EF Core 11 RC3 是预发布版本。升级并准备恢复 EnableDetailedErrors() 时,先确认应用实际加载的 EF Core 与数据库提供程序版本,在隔离环境重新启用该选项,并用同一组嵌套集合验证保存和变更检测。验证通过后再恢复应用配置;这项调整不需要数据库迁移。