Dapper WHERE子句使用参数字符串报@Filter附近语法错误
错误根因
你遇到的语法错误核心是误用了参数化查询的能力边界:
- 参数化查询只能用来传递查询值,无法直接传递
IS NULL这类SQL语法片段。你将IS NULL作为@Filter参数传入时,数据库驱动会自动给字符串值添加转义引号,最终生成的非法SQL如下:
SELECT * FROM table WHERE Name 'IS NULL' OR Email 'IS NULL'
语法自然不符合规范,触发@Filter附近报错。
- 你当前的SQL模板结构缺失操作符位,合法的WHERE条件结构为
字段 操作符 值,你只预留了一个参数位同时承载操作符和值,本身结构就存在问题。
修复方案
调整实现逻辑,仅动态拼接经过校验的SQL语法部分,查询值仍然用参数传递,既避免SQL注入风险,也能兼容多场景过滤:
public async Task<List<DTO>> Get(FilterDTO filter) { // 初始化SQL构建器和参数容器 var sqlBuilder = new StringBuilder("SELECT * FROM table WHERE 1=1 "); var parameters = new DynamicParameters(); // 可选:操作符白名单,避免非法拼接引发注入风险 var opMapping = new Dictionary<int, string> { {1, "IS NULL"}, {2, "="}, {3, "LIKE"} // 其他需要支持的操作符可自行扩展 }; foreach(var f in filter.fields) { if(!opMapping.ContainsKey(f.Operator)) continue; switch(f.Operator) { case 1: if(f.Value == null) { sqlBuilder.Append("AND (Name IS NULL OR Email IS NULL) "); break; } goto case 2; case 2: sqlBuilder.Append("AND (Name = @FilterValue OR Email = @FilterValue) "); parameters.Add("FilterValue", f.Value); break; // 其他操作符逻辑自行扩展 } } var queryResult = await connection.QueryAsync<Model>(sqlBuilder.ToString(), parameters); // 后续转换为DTO返回逻辑省略 }
额外注意点
如果需要支持LIKE等需要特殊处理值的场景,在参数赋值阶段处理即可,比如模糊查询时:
parameters.Add("FilterValue", $"%{f.Value}%");
内容的提问来源于stack exchange,提问作者Weenhallo
相关产品推荐
相关产品推荐

