postgresql 如何使用Npgsql从SELECT中获取所有查询结果

cotxawn7  于 5个月前  发布在  PostgreSQL
关注(0)|答案(2)|浏览(90)

我需要以JSON格式获取查询结果,但如果列是JSON数组,我会遇到问题:它会转换为字符串
我现在使用的代码:

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++)
        {
            row[reader.GetName(i)] = reader.GetValue(i);
        }
        result.Add(row);
    }
}

var jsonResult = JsonConvert.SerializeObject(result, Newtonsoft.Json.Formatting.Indented);
Console.WriteLine(jsonResult);

字符串
输出:

[
  {
    "id": 1,
    "banned": false,
    "strikes": "[]"
  },
  {
    "id": 2,
    "banned": false,
    "strikes": "[\"nooob\"]"
  }
]


EXCEPTED输出:

[
  {
    "id": 1,
    "banned": false,
    "strikes": []
  },
  {
    "id": 2,
    "banned": false,
    "strikes": ["nooob"]
  }
]

eoigrqb6

eoigrqb61#

似乎默认情况下Npgsql会将JSON列Map到字符串,因此您需要将其解析为JSON,以便序列化程序正确处理它(否则您将获得值“double”编码,如您所见)。

for (int i = 0; i < reader.FieldCount; i++)
{
    var name = reader.GetName(i);
    var value = reader.GetValue(i);
    value = name == "strikes" ? JArray.Parse(value) : value;
    row[name] = value;
}

字符串
请注意,according to docs可以更改默认Map。例如通过使用NpgsqlJsonNetExtensions(因为您使用的是Newtonsoft Json.NET序列化程序),因此您不需要手动执行以下操作:
要使用Json.NET,请将Npgsql.Json.NET包添加到您的项目中,并启用插件。

var dataSourceBuilder = new NpgsqlDataSourceBuilder(...);
dataSourceBuilder.UseJsonNet();
await using var dataSource = dataSourceBuilder.Build();


NpgsqlConnection.GlobalTypeMapper.UseJsonNet();


或者你可以考虑提供到一些已定义类型的Map--参见POCOMap文档。

9o685dep

9o685dep2#

这个问题是由于JSON数组被读取为字符串。要解决这个问题,您需要检查列的数据类型是否为JSON数组,然后相应地解析它。

for (int i = 0; i < reader.FieldCount; i++)
{
    if (reader.GetFieldType(i) == typeof(string) && reader.GetString(i).StartsWith("["))
    {
        row[reader.GetName(i)] = JsonConvert.DeserializeObject(reader.GetString(i));
    }
    else
    {
        row[reader.GetName(i)] = reader.GetValue(i);
    }
}

字符串

相关问题