Npgsql技术求助:传递数据表时复合类型字段匹配CLR类型报错
解决PostgreSQL复合类型与VB.NET List映射报错的方案
这个报错的核心原因是你搞混了单个复合类型和复合类型数组在CLR侧的映射关系——你试图把List<T>直接绑定到PostgreSQL的单个复合类型type_detalle_ac,但List本身没有id_componente这个属性,自然匹配失败。下面是具体的解决步骤:
1. 定义与复合类型完全匹配的CLR实体类
首先,你需要创建一个和PostgreSQL的type_detalle_ac字段一一对应的VB类,每个字段的名称(或通过特性映射)、数据类型必须完全匹配:
Imports System.ComponentModel.DataAnnotations.Schema ' 如果PostgreSQL复合类型用snake_case命名,用Column特性映射VB的PascalCase属性 Public Class DetalleAc <Column("id_componente")> Public Property IdComponente As Integer ' 对应复合类型的id_componente字段 ' 补充复合类型的其他字段,比如: ' <Column("nombre_componente")> ' Public Property NombreComponente As String ' ...其他字段 End Class
2. 正确注册复合类型映射
用MapCompositeGlobally注册单个实体类到PostgreSQL的复合类型,而不是直接注册List:
' 在应用初始化的地方(比如启动时)执行这个注册 NpgsqlConnection.GlobalTypeMapper.MapCompositeGlobally(Of DetalleAc)("public.type_detalle_ac")
3. 以复合类型数组的形式传递集合
PostgreSQL中,多个复合类型的集合对应复合类型数组(即type_detalle_ac[]),所以你需要把List(Of DetalleAc)转换成数组后再传递给参数:
' 示例:插入数据到包含复合类型数组的表 Dim misDetalles As New List(Of DetalleAc)() ' 向列表中添加实体对象 misDetalles.Add(New DetalleAc With { .IdComponente = 1 }) misDetalles.Add(New DetalleAc With { .IdComponente = 2 }) Using conn As New NpgsqlConnection("你的数据库连接字符串") conn.Open() Using cmd As New NpgsqlCommand("INSERT INTO tu_tabla (columna_detalles) VALUES (@detalles)", conn) ' 把List转换成数组,传递给参数 cmd.Parameters.AddWithValue("@detalles", misDetalles.ToArray()) cmd.ExecuteNonQuery() End Using End Using
额外注意事项
- 确保Npgsql版本是最新稳定版,旧版本可能对复合类型映射支持不全;
- 如果是调用存储过程,要确保存储过程的参数类型是
public.type_detalle_ac[],而不是单个type_detalle_ac; - 字段名称匹配:如果PostgreSQL的复合类型字段是小写snake_case,而VB用PascalCase命名属性,一定要用
Column特性明确映射,避免因大小写不匹配导致的字段找不到问题。
内容的提问来源于stack exchange,提问作者nasck
相关产品推荐
相关产品推荐

