使用Npgsql执行SELECT查询时JSON数组列被转为字符串的问题
解决Npgsql查询中JSON数组列被序列化为字符串的问题
问题原因
你当前代码中reader.GetValue(i)会把PostgreSQL的json/jsonb类型列直接返回为字符串,Newtonsoft.Json序列化时会保留字符串的引号,导致JSON数组变成带引号的字符串格式。
解决方案1:读取时手动解析JSON列
在读取每列数据时,判断字段类型是否为json或jsonb,将其解析为Newtonsoft.Json的JArray类型,这样序列化时会自动转换为原生JSON数组格式。
修改后的代码:
using Newtonsoft.Json.Linq; // 需引入该命名空间 var result = new List<Dictionary<string, object>>(); await using (var cmd = new NpgsqlCommand("SELECT * FROM global", conn)) await using (var reader = await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { var row = new Dictionary<string, object>(); for (int i = 0; i < reader.FieldCount; i++) { var fieldName = reader.GetName(i); var dataType = reader.GetDataTypeName(i); if (reader.IsDBNull(i)) { row[fieldName] = null; continue; } // 判断是否为JSON类型列 if (dataType == "json" || dataType == "jsonb") { var jsonStr = reader.GetString(i); // 解析为JArray,空字符串处理为空数组 row[fieldName] = string.IsNullOrWhiteSpace(jsonStr) ? JArray.Parse("[]") : JArray.Parse(jsonStr); } else { row[fieldName] = reader.GetValue(i); } } result.Add(row); } } var jsonResult = JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented); Console.WriteLine(jsonResult);
解决方案2:使用强类型实体类
定义与数据库表结构匹配的实体类,利用Npgsql的类型映射自动将JSON列转换为JArray或List<string>,序列化时自然保持数组格式。
步骤1:定义实体类
using Newtonsoft.Json.Linq; public class GlobalRecord { public int Id { get; set; } public bool Banned { get; set; } // 若确定strikes是字符串数组,也可替换为List<string> public JArray Strikes { get; set; } }
步骤2:修改查询代码
var result = new List<GlobalRecord>(); await using (var cmd = new NpgsqlCommand("SELECT * FROM global", conn)) await using (var reader = await cmd.ExecuteReaderAsync()) { while (await reader.ReadAsync()) { result.Add(new GlobalRecord { Id = reader.GetInt32(reader.GetOrdinal("id")), Banned = reader.GetBoolean(reader.GetOrdinal("banned")), // 直接读取为JArray类型 Strikes = reader.GetFieldValue<JArray>(reader.GetOrdinal("strikes")) }); } } var jsonResult = JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented); Console.WriteLine(jsonResult);
补充说明
如果你的项目使用System.Text.Json而非Newtonsoft.Json,可以将JArray替换为JsonElement或JsonDocument,序列化逻辑保持一致。
内容的提问来源于stack exchange,提问作者dummy_dumdum21
相关产品推荐
相关产品推荐

