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

PostgreSQL+Dapper绑定VALUES子串时多余双引号问题求助

解决方案:PostgreSQL+Dapper拼接VALUES出现多余双引号问题

问题根源

你遇到的多余双引号,是因为直接用string.Format拼接后,误将拼接结果作为参数传递给Dapper,Dapper会自动给字符串参数添加引号进行转义;另外手动拼接SQL还存在严重的SQL注入风险,不推荐这么做。

推荐解决方案(无注入风险,彻底解决引号问题)

方案1:多参数化VALUES子句

通过为每个GameId和Count单独创建参数,让Dapper自动处理类型和转义,完全避免手动拼接字符串:

using Dapper;
using System.Data;
using Npgsql; // PostgreSQL的ADO.NET驱动

// 准备参数集合
var parameters = new DynamicParameters();
var valueItems = new List<string>();
int paramIndex = 0;

foreach (var item in ListGameIdCountResponse)
{
    // 生成唯一参数名
    var gameIdParam = $"@GameId{paramIndex}";
    var countParam = $"@Count{paramIndex}";
    
    // 添加参数(Dapper会自动处理Guid类型映射)
    parameters.Add(gameIdParam, item.GameId, DbType.Guid);
    parameters.Add(countParam, item.Count, DbType.Int32);
    
    // 构造VALUES中的子句
    valueItems.Add($"({gameIdParam}, {countParam})");
    paramIndex++;
}

// 拼接完整SQL
var sql = $@"SELECT g.""Name"", g.""Id""
FROM ""Games"" g
LEFT JOIN (VALUES {string.Join(",", valueItems)}) AS TrendingGameCount (GameId, Count)
ON g.""Id"" = TrendingGameCount.GameId::uuid
ORDER BY TrendingGameCount.Count DESC";

// 执行查询
using var connection = new NpgsqlConnection("你的连接字符串");
var result = connection.Query<YourResultModel>(sql, parameters);

方案2:使用PostgreSQL数组+unnest函数(更简洁)

利用PostgreSQL的数组特性,直接传递GameId和Count数组,通过unnest函数展开为临时表:

using Dapper;
using Npgsql;

// 提取数组数据
var gameIds = ListGameIdCountResponse.Select(p => p.GameId).ToArray();
var counts = ListGameIdCountResponse.Select(p => p.Count).ToArray();

// 编写参数化SQL
var sql = @"SELECT g.""Name"", g.""Id""
FROM ""Games"" g
LEFT JOIN unnest(@GameIds, @Counts) AS TrendingGameCount (GameId, Count)
ON g.""Id"" = TrendingGameCount.GameId::uuid
ORDER BY TrendingGameCount.Count DESC";

// 执行查询(Dapper自动映射.NET数组到PostgreSQL数组)
using var connection = new NpgsqlConnection("你的连接字符串");
var result = connection.Query<YourResultModel>(sql, new { GameIds = gameIds, Counts = counts });

不推荐的临时方案(仅作参考,有注入风险)

如果一定要坚持手动拼接(仅当GameId是数据库返回的Guid、Count是整数,完全不可控时勉强可用),需要直接拼接成完整SQL字符串后传给Dapper,而不是把拼接结果作为参数:

// 注意:此方法存在SQL注入风险,禁止用于用户输入相关场景
var valuesClause = string.Join(',', ListGameIdCountResponse.Select(p => $"('{p.GameId}', {p.Count})"));
var sql = $@"SELECT g.""Name"", g.""Id""
FROM ""Games"" g
LEFT JOIN (VALUES {valuesClause}) AS TrendingGameCount (GameId, Count)
ON g.""Id"" = TrendingGameCount.GameId::uuid
ORDER BY TrendingGameCount.Count DESC";

using var connection = new NpgsqlConnection("你的连接字符串");
var result = connection.Query<YourResultModel>(sql);

内容的提问来源于stack exchange,提问作者Choi Xong Zong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:48:17