.NET 6调用带复合类型参数的PostgreSQL存储过程报错求助
解决PostgreSQL复合类型数组传入存储过程的InvalidCastException错误
错误原因
你直接将List<myObject>映射到PostgreSQL的复合类型数组composite[],但Npgsql需要先注册单个复合类型,才能自动处理该类型的数组;另外参数配置方式也可能导致类型推断失败。
修复步骤
确保.NET类与PostgreSQL复合类型字段匹配
假设你的PostgreSQL复合类型定义如下:CREATE TYPE composite AS ( id integer, acquisition_date timestamp, price numeric, -- 其他字段需与BulkUpdateAcquisitionDto的属性一一对应 );对应的.NET类要保证属性名一致,或者用
[PgName]特性指定字段名:public class BulkUpdateAcquisitionDto { public int Id { get; set; } [PgName("acquisition_date")] public DateTime AcquisitionDate { get; set; } public decimal Price { get; set; } // 其他对应属性 }正确注册复合类型映射
不要直接映射List<T>,先注册单个复合类型,Npgsql会自动支持该类型的数组:var dataSourceBuilder = new NpgsqlDataSourceBuilder(_connectionString); // 注册单个复合类型,而非数组 dataSourceBuilder.MapComposite<BulkUpdateAcquisitionDto>("composite"); await using var dataSource = dataSourceBuilder.Build();简化存储过程调用代码
利用NpgsqlDataSource创建命令,让Npgsql自动处理类型推断,避免手动设置DataTypeName时出错:using var conn = dataSource.CreateConnection(); await conn.OpenAsync(); // 直接通过数据源创建命令,继承类型映射配置 using var command = dataSource.CreateCommand("\"schema\".\"procedureName\""); command.CommandType = CommandType.StoredProcedure; // 直接传入List<BulkUpdateAcquisitionDto>类型的参数值 command.Parameters.AddWithValue("paramName", paramValue); await command.ExecuteNonQueryAsync();
额外注意事项
- 检查存储过程的参数类型是否为
composite[],确保定义正确:CREATE OR REPLACE FUNCTION schema.procedureName(paramName composite[]) RETURNS void AS $$ BEGIN -- 存储过程逻辑 END; $$ LANGUAGE plpgsql; - 如果必须手动指定
DataTypeName,确保值为"composite[]",且已完成单个复合类型的注册。
内容的提问来源于stack exchange,提问作者User7291
相关产品推荐
相关产品推荐

