如何使用Npgsql向PostgreSQL 15存储过程传递自定义类型数组
在.NET中使用Npgsql传递PostgreSQL自定义类型数组给存储过程
要实现这个需求,分三步操作即可:
1. 定义对应PostgreSQL自定义类型的.NET类
先在.NET项目里创建一个类,和PostgreSQL的key_value_int_int类型字段一一对应,同时加上Npgsql的复合类型映射特性,让Npgsql能识别这个类型:
using NpgsqlTypes; [NpgsqlCompositeType(Name = "key_value_int_int", Schema = "public")] public class KeyValueIntInt { [NpgsqlColumnName("key")] public int Key { get; set; } [NpgsqlColumnName("value")] public int Value { get; set; } }
注意:类名可自定义,但NpgsqlCompositeType的Name必须和PostgreSQL里的自定义类型名完全一致,Schema要指定类型所在的模式(这里是public);属性上的NpgsqlColumnName要和PostgreSQL类型里的字段名精准匹配(因为PostgreSQL里用双引号定义了"key"和"value")。
2. 注册自定义类型映射
在建立数据库连接前,把刚才定义的.NET类和PostgreSQL的自定义类型做映射注册——全局注册一次即可,比如放在项目启动代码里:
NpgsqlConnection.GlobalTypeMapper.MapComposite<KeyValueIntInt>();
如果只需要在当前连接生效,也可以在打开连接前局部注册:
conn.TypeMapper.MapComposite<KeyValueIntInt>();
3. 修改代码调用存储过程
把原来的文本命令调用改成存储过程调用,直接传递数组参数:
// 准备要传递的数组数据 var dictionaryItems = new[] { new KeyValueIntInt { Key = 1, Value = 100 }, new KeyValueIntInt { Key = 2, Value = 200 } }; await using var conn = new NpgsqlConnection(GetConnectionString()); await using var command = new NpgsqlCommand("sp_update_table", conn); command.CommandType = CommandType.StoredProcedure; // 添加对应存储过程的参数 command.Parameters.AddWithValue("p_id", 123); // 替换为实际的ID值 command.Parameters.AddWithValue("p_dictionary", dictionaryItems); try { await conn.OpenAsync(); await command.ExecuteNonQueryAsync(); } catch (Exception ex) { Debug.WriteLine(ex); throw AsDatabaseException(ex); }
关键细节
- 存储过程的参数名要和PostgreSQL里定义的完全一致(
p_id和p_dictionary),Npgsql会按参数名匹配,顺序不影响。 - 传递数组时直接传
KeyValueIntInt[]类型的数组即可,Npgsql会自动转换成PostgreSQL的key_value_int_int[]类型。 - 确保已安装兼容的
NpgsqlNuGet包,推荐6.x及以上版本适配PostgreSQL 15。
内容的提问来源于stack exchange,提问作者Roman M
相关产品推荐
相关产品推荐

