You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Dapper构建动态参数化查询?解决特殊字符报错问题

解决方案

你的核心问题是直接字符串拼接SQL导致的特殊字符冲突,还存在严重的SQL注入风险,用参数化查询就能完美解决,下面给你两种靠谱的实现方式:

方法一:用CommandDefinition构建参数化查询

这个思路很清晰:先动态生成带参数占位符的SQL,再把键值对转换成Dapper能识别的参数集合,最后用CommandDefinition把SQL和参数打包执行,完全避开字符串拼接的问题。

代码实现:

string statement = "SELECT * FROM Employee WHERE 1 = 1 ";
List<KeyValuePair<string, string>> lst = new List<KeyValuePair<string, string>>();
lst.Add(new KeyValuePair<string, string>("FName", "Kim"));
lst.Add(new KeyValuePair<string, string>("LName", "O'reily"));
lst.Add(new KeyValuePair<string, string>("Gender", "Male"));

// 1. 构建带参数占位符的SQL,并把值加入参数集合
var parameters = new DynamicParameters();
foreach (var kvp in lst)
{
    var paramName = $"@{kvp.Key}";
    statement += $" AND {kvp.Key} = {paramName} ";
    parameters.Add(paramName, kvp.Value);
}

// 2. 用CommandDefinition打包SQL和参数,执行查询
using (var connection = _dataAccessHelper.GetOpenConnection())
{
    try
    {
        var cmd = new CommandDefinition(statement, parameters, commandType: CommandType.Text);
        var searchResult = await connection.QueryAsync<dynamic>(cmd);
        // 这里可以处理你的查询结果
    }
    catch (Exception ex)
    {
        // 按需添加异常处理逻辑
        throw;
    }
}

方法二:更简洁的方式——用LINQ简化代码

如果觉得循环写起来麻烦,可以用LINQ把键值对直接转换成参数和查询条件,代码会更紧凑:

// 初始化你的键值对列表
var lst = new List<KeyValuePair<string, string>>
{
    new("FName", "Kim"),
    new("LName", "O'reily"),
    new("Gender", "Male")
};

var parameters = new DynamicParameters();
// 用LINQ生成每个查询条件,同时把参数加入集合
var conditions = lst.Select(kvp => 
{
    var paramName = $"@{kvp.Key}";
    parameters.Add(paramName, kvp.Value);
    return $"{kvp.Key} = {paramName}";
});

// 拼接最终的SQL语句
string statement = $"SELECT * FROM Employee WHERE 1 = 1 AND {string.Join(" AND ", conditions)}";

using (var connection = _dataAccessHelper.GetOpenConnection())
{
    try
    {
        // 直接用参数执行,或者用CommandDefinition都可以
        var searchResult = await connection.QueryAsync<dynamic>(statement, parameters);
        // 或者用CommandDefinition的写法:
        // var cmd = new CommandDefinition(statement, parameters);
        // var searchResult = await connection.QueryAsync<dynamic>(cmd);
    }
    catch (Exception ex)
    {
        // 异常处理
    }
}

为什么这两种方法能解决问题?

  • 完全避免了直接拼接字符串,Dapper会自动处理参数里的特殊字符(比如O'reily里的单引号会被安全转义)
  • 彻底杜绝了SQL注入风险,这是生产环境必须注意的安全要点
  • DynamicParameters是Dapper专门为动态参数设计的工具,和CommandDefinition配合使用非常顺畅,能灵活应对各种动态查询场景

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

火山引擎 最新活动