.NET Core向PostgreSQL存储JSON时遇IEnumerable参数不支持问题
问题解决:.NET Core向PostgreSQL插入JSON数据时抛出IEnumerable参数不支持异常
错误分析
你遇到的System.NotSupportedException: IEnumerable parameters are not supported, pass an array or List instead异常,核心原因是Npgsql无法直接将JObject类型解析为PostgreSQL的JSON参数,或者你的customer.tags本身是可枚举集合,序列化后转换为JObject时被Npgsql识别为IEnumerable类型,导致参数处理失败。此外,原循环代码存在重复添加参数的问题,会引发额外错误。
解决方案
方案1:直接传递JSON字符串(最简单)
PostgreSQL的json/jsonb字段可以直接接收JSON格式的字符串,无需转换为JObject:
string strCommandInsert = @"INSERT INTO public.""City"" (""id"", ""externalId"", ""tags"", ""members"", ""geometry"") values (@id, @externalId, @tags, @members, @geometry);"; foreach (var customer in cities.elements) { // 直接序列化tags为JSON字符串 var tagsJson = JsonConvert.SerializeObject(customer.tags); await using (var command = new NpgsqlCommand(strCommandInsert, conn)) { command.Parameters.AddWithValue("@id", customer.id); command.Parameters.AddWithValue("@externalId", Guid.NewGuid()); // 直接传递JSON字符串 command.Parameters.AddWithValue("@tags", tagsJson); // 补充其他未赋值的参数(根据实际业务逻辑替换为真实值) command.Parameters.AddWithValue("@members", DBNull.Value); command.Parameters.AddWithValue("@geometry", DBNull.Value); int nRows = command.ExecuteNonQuery(); await Console.Out.WriteLineAsync($"Number of rows inserted={nRows}"); } }
方案2:使用Npgsql的Json.NET扩展支持
如果需要保持JObject类型的操作,可通过Npgsql官方的Json.NET扩展来处理:
- 首先安装NuGet包:
Npgsql.Json.NET - 修改代码指定参数类型:
string strCommandInsert = @"INSERT INTO public.""City"" (""id"", ""externalId"", ""tags"", ""members"", ""geometry"") values (@id, @externalId, @tags, @members, @geometry);"; foreach (var customer in cities.elements) { var tagsJson = JsonConvert.SerializeObject(customer.tags); var jObject = JObject.Parse(tagsJson); await using (var command = new NpgsqlCommand(strCommandInsert, conn)) { command.Parameters.AddWithValue("@id", customer.id); command.Parameters.AddWithValue("@externalId", Guid.NewGuid()); // 指定NpgsqlDbType.Json类型,传递JObject command.Parameters.AddWithValue("@tags", NpgsqlDbType.Json, jObject); // 补充其他参数 command.Parameters.AddWithValue("@members", DBNull.Value); command.Parameters.AddWithValue("@geometry", DBNull.Value); int nRows = command.ExecuteNonQuery(); await Console.Out.WriteLineAsync($"Number of rows inserted={nRows}"); } }
关键注意事项
- 必须确保数据库中
tags字段的类型是json或jsonb,否则会出现类型不匹配错误。 - 将
NpgsqlCommand的创建放到循环内部,避免重复添加参数导致的参数重复异常。 - 代码中未处理
@members和@geometry参数,需根据实际业务逻辑赋值,否则会因参数缺失抛出错误。
内容的提问来源于stack exchange,提问作者Cyrus the Great
相关产品推荐
相关产品推荐

