Npgsql 连 Guid 数组都写不进去,检查动态 JSON 注册的结构体
Npgsql 10.0.2 中,EnableDynamicJson 注册值类型可能让无关数组参数失败。内层 Nullable 泛型约束错误比外层 Guid[] 报错更接近原因。
Guid[] 参数已明确设为 NpgsqlDbType.Array | NpgsqlDbType.Uuid,仍报 Writing values of 'System.Guid[]' is not supported。如果内层异常还提到 Nullable<ActivityContext> 和 violates the constraint of type 'TElement',应检查动态 JSON 注册,别先把 UUID 数组改成字符串。
Npgsql 10.0.2 的明确触发条件是:数据源的 EnableDynamicJson 类型列表中包含结构体,例如 ActivityContext。数组类型解析会建立动态 JSON 数组映射,处理 Nullable 映射时违反泛型约束,外层便显示当前正在解析的 Guid 数组不受支持。报错中的参数类型不一定是出错注册项本身。
先看完整内层异常
保留运行时实际解析到的 Npgsql 版本、数据源构造代码和异常链。确认同一个 NpgsqlDataSource 是否调用了 EnableDynamicJson,列表中有哪些 Type,并查看是否出现 JsonDynamicTypeInfoResolverFactory.ArrayResolver 与 AddArrayMapping。
如果没有动态 JSON 配置,或内层异常不是 Nullable 泛型约束,这条路径就不充分。继续核对参数元素类型、数据库目标类型与自定义映射,不能看到 Guid 数组就统一按本题处理。
核对 10.0.3 的正式修正
Npgsql 10.0.3 的正式源码已将可空值类型按底层类型处理,并在批量建立数组映射时跳过独立的 Nullable<T> 项。该版本已在 NuGet 正式发布,可以在项目分支中按依赖约束升级验证。
保留项目文件与锁文件,检查 EF Core 提供程序、插件及传递依赖是否允许这一补丁版本。部署前再看实际运行进程加载的版本,不能只确认顶层包声明已变。
暂时无法升级时,若注册列表中某个结构体并非业务所需,可以在测试分支移除该项并重新构造数据源,判断数组参数是否恢复。不要盲目移除所有 JSON 映射:真正依赖该结构体序列化的查询会受影响。需要保留功能时,应选择经过验证的驱动修正,而不是全局关闭类型检查。
数据源通常应按应用生命周期管理。修改构造配置后按原有启动流程切换,不要为每条 SQL 临时创建数据源,也不要把原连接串中的 TLS 或认证选项改掉来试数组映射。
验收同时覆盖原来的 Guid 数组、包含 SQL NULL 语义的参数,以及实际需要的 JSON 结构体读写。数组能写入只证明外层错误消失;还需确认 JSON 字段、可空值和读回结果符合原契约。回退时恢复配套依赖与注册配置,数据类型本身无需为这次驱动映射错误改表。


