You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中用EF操作jsonb字段报错:输入字符串格式不正确

问题根源

你写的SQL里,JSON字符串被双重转义了:\"是HTML转义的引号(原本的"被转成"),又在字符串里加了反斜杠转义,导致数据库收到的是不合法的JSON格式(比如\"age\"不是有效的JSON键名),自然触发格式错误。另外直接硬编码换行符\r\n也没必要,PostgreSQL的jsonb不关心换行,只要结构合法就行。

解决方法

方法1:修正SQL字符串的转义

把HTML转义的\"还原成普通双引号,同时确保SQL里的字符串用单引号正确包裹,不需要额外转义双引号(因为JSON内部的双引号不属于SQL字符串的边界)。修正后的SQL应该是:

INSERT INTO example_table (id, name, details) 
VALUES (1, 'john','{"age": "17"}') 
ON CONFLICT (name) DO NOTHING

对应的C#代码:

_context.ExecuteSqlRaw("INSERT INTO example_table (id, name, details) VALUES (1, 'john','{\"age\": \"17\"}') ON CONFLICT (name) DO NOTHING");

这里C#字符串里的双引号用\"转义,确保传到数据库的是{"age": "17"}这个合法的JSON。

方法2:用参数化查询(推荐)

直接拼接SQL字符串容易出转义问题,还可能有SQL注入风险,用参数化查询更安全可靠:

var id = 1;
var name = "john";
var details = "{\"age\": \"17\"}"; // 或者用序列化工具把对象转成JSON字符串
_context.ExecuteSqlRaw(
    "INSERT INTO example_table (id, name, details) VALUES ({0}, {1}, {2}) ON CONFLICT (name) DO NOTHING",
    id, name, details
);

如果你的details是C#对象,可以用System.Text.Json或Newtonsoft.Json序列化成JSON字符串再传入,比如:

var detailsObj = new { age = "17" };
var detailsJson = JsonSerializer.Serialize(detailsObj);
_context.ExecuteSqlRaw(
    "INSERT INTO example_table (id, name, details) VALUES ({0}, {1}, {2}) ON CONFLICT (name) DO NOTHING",
    1, "john", detailsJson
);

方法3:用EF Core的原生Upsert(更符合EF用法)

如果你不想写原生SQL,可以用EF Core 7+支持的OnConflict逻辑,直接操作实体类:

var entity = new ExampleTable { Id = 1, Name = "john", Details = JsonSerializer.SerializeToElement(new { age = "17" }) };
_context.ExampleTable.Add(entity);
_context.SaveChanges();
// 或者用Upsert扩展(需安装Microsoft.EntityFrameworkCore.Relational包)
_context.ExampleTable
    .Upsert(entity)
    .On(e => e.Name)
    .DoNothing()
    .Execute();

这里假设你的实体类里Details字段对应数据库的jsonb类型,EF Core会自动处理JSON的序列化和转义。

内容的提问来源于stack exchange,提问作者user2382627

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 15:10:44