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

升级Npgsql至v8后枚举类型数组映射的读写异常求助

Npgsql 7.x升级至8.x后枚举数组读写异常解决

问题背景

将Npgsql从7.0.11版本升级到8.0.2/8.0.3版本,PostgreSQL中定义了如下枚举类型:

CREATE TYPE my_type AS ENUM (...)

SQL中读写该枚举类型的方式:

SELECT foo::my_type FROM BAR
SELECT foo FROM BAR
INSERT INTO BAR(foo) VALUES(@Foo::my_type)

遇到的异常

  1. 首次写入时报错:

Writing values of 'MyType[]' is not supported for parameters having no NpgsqlDbType or DataTypeName

  1. 调用以下代码修复写入问题后,出现读取异常:
NpgsqlConnection.GlobalTypeMapper.MapEnum<MyType>("public.my_type", new CustomEnumTranslator());

读取错误信息:

System.Data.DataException : Error parsing column 5 (foo=MyType[] - Object)
---- System.InvalidCastException : Unable to cast object of type 'MyType[]' to type 'System.String[]'.

异常场景:方法参数object value运行时实际为MyType[2](包含2个枚举值的数组),但程序代码尝试将其强制转换为string[]。

解决步骤

  • 补全枚举数组的类型映射:在注册单个枚举类型后,显式注册枚举数组的类型映射,让Npgsql能正确识别并处理数组类型:
// 注册基础枚举类型
NpgsqlConnection.GlobalTypeMapper.MapEnum<MyType>("public.my_type", new CustomEnumTranslator());
// 注册枚举数组类型
NpgsqlConnection.GlobalTypeMapper.MapArray<MyType>();
  • 修正读取逻辑:避免直接将MyType[]强制转换为string[],如果需要字符串数组,可通过显式转换实现:
// 示例:将枚举数组转换为字符串数组
var myTypeArray = (MyType[])value;
var stringArray = myTypeArray.Select(item => item.ToString()).ToArray();
  • 使用强类型读取方法:如果通过NpgsqlDataReader读取数据,直接使用GetFieldValue<T>()方法获取枚举数组,避免GetValue()后的类型转换问题:
var fooArray = reader.GetFieldValue<MyType[]>(5);
  • 简化SQL查询:移除查询中不必要的类型转换,直接读取枚举类型字段,减少隐式转换带来的冲突:
-- 推荐写法,避免多余的::my_type转换
SELECT foo FROM BAR

内容的提问来源于stack exchange,提问作者Nikita Kalimov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:02:45