如何用Npgsql 7在.NET 6中向PostgreSQL函数传复合类型数组参数
PostgreSQL复合类型数组参数传递方案(替代MSSQL表值参数)
一、先在PostgreSQL端定义复合类型与函数
首先需要在数据库中创建对应C#类的复合类型,以及接收该类型数组的函数:
-- 创建复合类型(字段名与C#类属性对应) CREATE TYPE your_composite_type AS ( column1 VARCHAR(50), column2 INT ); -- 创建接收复合类型数组的函数 CREATE OR REPLACE FUNCTION your_function_name(your_parameter_name your_composite_type[]) RETURNS INT AS $$ BEGIN -- 示例逻辑:返回数组长度,替换为你的业务逻辑 RETURN array_length(your_parameter_name, 1); END; $$ LANGUAGE plpgsql;
二、.NET侧配置复合类型映射
在应用启动阶段(如Program.cs)注册C#类与PostgreSQL复合类型的映射,让Npgsql能够自动识别类型:
// 全局注册复合类型映射,需在创建数据库连接前执行 NpgsqlConnection.GlobalTypeMapper.MapComposite<YourCompositeType>("your_composite_type");
对应的C#类定义需与PostgreSQL复合类型字段匹配,字段名不一致时可通过[Column]特性指定:
public class YourCompositeType { // 与PG复合类型字段名一致,无需特性 public string Column1 { get; set; } public int Column2 { get; set; } // 构造函数 public YourCompositeType(string column1, int column2) { Column1 = column1; Column2 = column2; } } // 若字段名不匹配的情况示例 // public class YourCompositeType // { // [Column("column1")] // public string MyCustomColumnName { get; set; } // [Column("column2")] // public int MyCustomIntColumn { get; set; } // }
三、修正后的函数调用代码
Npgsql 7中无需手动指定NpgsqlDbType.Composite,只要完成类型映射,即可直接传递数组参数,Npgsql会自动处理类型转换:
using (var connection = new NpgsqlConnection("your_connection_string")) { connection.Open(); // 若未全局注册,也可在当前连接上单独注册 // connection.TypeMapper.MapComposite<YourCompositeType>("your_composite_type"); var command = new NpgsqlCommand("your_function_name", connection); command.CommandType = CommandType.StoredProcedure; // 构造复合类型数组 var compositeTypeArray = new[] { new YourCompositeType("value1", 1), new YourCompositeType("value2", 2) }; // 直接传递数组,无需手动指定复合类型 var parameter = new NpgsqlParameter("your_parameter_name", compositeTypeArray); command.Parameters.Add(parameter); var result = command.ExecuteScalar(); Console.WriteLine(result); }
常见问题排查
- 确保PostgreSQL复合类型名称与映射时传入的字符串完全匹配(区分大小写,若创建类型时使用双引号包裹名称,映射时也需带双引号)
- C#类的属性数量、数据类型必须与PostgreSQL复合类型的字段一一对应
- 若使用控制台应用,全局类型注册代码需放在创建
NpgsqlConnection实例之前执行
内容的提问来源于stack exchange,提问作者Ajinkya Kulkarni
相关产品推荐
相关产品推荐

