Npgsql传递Category列表至存储过程时lstOtherItems丢失问题求助
解决嵌套列表在PostgreSQL存储过程中丢失的问题
核心原因分析
问题出在自定义类型arjsnCategory的结构不匹配或Npgsql参数类型配置错误,导致嵌套的lstOtherItems字段未被正确映射或序列化传递。
分步解决方案
1. 修正PostgreSQL自定义类型定义
如果坚持使用自定义类型arjsnCategory,必须确保其结构完全匹配.NET的Category类,包括嵌套的列表字段。例如:
-- 先定义嵌套的OtherItems类型(适用于简单结构) CREATE TYPE OtherItems AS ( item_id INT, item_name TEXT ); -- 定义包含嵌套列表的Category类型 CREATE TYPE arjsnCategory AS ( category_id INT, category_name TEXT, lstotheritems OtherItems[] -- 字段名需与.NET类序列化后的属性名一致 );
如果OtherItems是复杂多层嵌套结构,建议直接用jsonb存储嵌套列表,适配性更强:
CREATE TYPE arjsnCategory AS ( category_id INT, category_name TEXT, lstotheritems JSONB );
2. 调整Npgsql参数配置
不要混用NpgsqlDbType.Jsonb|NpgsqlDbType.Array的写法,需明确参数类型层级:
- 如果参数是
jsonb[](JSONB数组):
var param = new NpgsqlParameter("@categoryList", NpgsqlDbType.Array | NpgsqlDbType.Jsonb) { Value = categoryList // Npgsql会自动将List<Category>序列化为jsonb[] };
- 如果使用自定义复合类型
arjsnCategory[]:
// 需确保Category类与自定义类型字段完全匹配,Npgsql会自动映射 var param = new NpgsqlParameter("@categoryList", NpgsqlDbType.Array) { Value = categoryList, DataTypeName = "arjsnCategory" // 指定自定义类型名称 };
3. 确保.NET对象序列化正确
检查Category和OtherItems类的序列化配置,避免嵌套字段被忽略:
using System.Text.Json.Serialization; public class Category { public int CategoryId { get; set; } public string CategoryName { get; set; } // 禁止添加[JsonIgnore]属性,可通过JsonPropertyName映射字段名 [JsonPropertyName("lstotheritems")] public List<OtherItems> LstOtherItems { get; set; } } public class OtherItems { public int ItemId { get; set; } public string ItemName { get; set; } }
4. 优化存储过程参数接收
如果不需要严格的自定义类型,直接使用jsonb[]作为参数类型可避免类型映射问题,实现更简单:
CREATE OR REPLACE PROCEDURE process_categories(p_categories JSONB[]) LANGUAGE plpgsql AS $$ BEGIN -- 遍历数组并访问嵌套字段 FOR i IN 1..array_length(p_categories, 1) LOOP -- 提取并验证嵌套的lstOtherItems RAISE NOTICE 'Category: %, OtherItems Count: %', p_categories[i]->>'category_name', jsonb_array_length(p_categories[i]->'lstotheritems'); END LOOP; END; $$;
5. 验证Npgsql版本
确保使用最新稳定版Npgsql(≥6.0),旧版本对嵌套对象的数组序列化存在兼容性问题。
内容的提问来源于stack exchange,提问作者JUNAID M
相关产品推荐
相关产品推荐

