使用FlexLabs.Upsert时Postgres Upsert需重设主键才生效问题
问题分析与解决
首先看你提供的无法更新的SQL,存在明显语法错误:SET子句的最后一列"active" = EXCLUDED."active"后面多了个逗号,PostgreSQL会因为这个语法错误直接拒绝执行ON CONFLICT后的更新逻辑,这就是行未被更新的核心原因。
你提到能正常工作的SQL,虽然添加了主键赋值,但实际也存在语法问题("id" = @p10后缺少逗号),推测是你手动修改时的笔误,不过这也从侧面说明,当你调整SQL结构后,语法错误被意外规避,才触发了更新逻辑。
解决步骤
修正SQL语法错误
确保SET子句的最后一列后无多余逗号,正确的SQL示例:INSERT INTO "Table" AS "T" ( "id", "active", "status", "price", "modified_date") VALUES (@p0, @p1, @p2, @p3, @p4), (@p5, @p6, @p7, @p8, @p9) ON CONFLICT ("id") DO UPDATE SET "modified_date" = EXCLUDED."modified_date", "active" = EXCLUDED."active"检查FlexLabs.Upsert配置与版本
这个语法错误大概率是库生成SQL时的bug,建议:- 升级到FlexLabs.Upsert的最新版本,旧版本可能存在自动生成SQL时多添逗号的问题;
- 在代码中明确指定要更新的列,避免库自动生成逻辑出错,示例代码:
await dbContext.Table .UpsertRange(yourEntities) .On(t => t.Id) .UpdateOnly(t => new { t.ModifiedDate, t.Active }) // 明确指定更新列 .RunAsync();
验证冲突触发条件
你的表主键Id为手动赋值(DatabaseGeneratedOption.None),需确保插入的Id确实存在于表中,否则ON CONFLICT不会触发更新,只会执行插入操作。
额外排查点
- 查看PostgreSQL日志,确认执行SQL时是否有语法错误或其他异常;
- 用手动编写的正确SQL直接执行,验证是否能正常更新,排除库以外的问题。
内容的提问来源于stack exchange,提问作者user21389840
相关产品推荐
相关产品推荐

