如何使用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




