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

Dapper ORM带NULL检查的IN列表查询报错:原因及非动态SQL方案咨询

Dapper处理IN参数的常见问题解答

问题背景

执行以下Dapper代码时触发SQL异常:

List<string> valueList = new List<string> { "20230626", "20230808"};
string sql = "SELECT * FROM MyTable WHERE @Values IS NULL OR Value IN @Values";
var result = connection.Query<dynamic>(sql, new { Values = valueList });

报错信息:

SqlException: an expression of non-boolean type specified in a context where a condition is expected, near ','

以下两种场景可正常运行:

  • 将valueList设为null
  • 移除SQL语句中的@Values IS NULL检查

疑问解答

1. 使用IN参数时,Dapper是否会重写查询语句?

是的。当传入集合类型(如List<string>)作为@Values参数时,Dapper会自动重写SQL语句:它会把IN @Values替换为IN (@p0, @p1, ...),同时为集合中的每个元素生成独立的参数。

原SQL报错的根源在于:Dapper只重写IN后的@Values,不会处理前面的@Values IS NULL判断,最终生成的非法SQL会是WHERE (@p0, @p1) IS NULL OR Value IN (@p0, @p1),而(@p0, @p1) IS NULL是无效的布尔表达式。

2. 是否存在无需使用动态SQL或表值参数的解决方案?

有两种简洁可行的方案:

方案一:拆分NULL判断为独立参数

通过额外传递布尔参数控制NULL分支,避免直接对集合参数做IS NULL判断:

List<string> valueList = new List<string> { "20230626", "20230808"};
bool isValuesEmpty = valueList == null || !valueList.Any();
string sql = @"SELECT * FROM MyTable 
               WHERE @IsValuesEmpty = 1 OR Value IN @Values";
// 集合为空时传空列表,避免Dapper处理null参数的问题
var parameters = new { IsValuesEmpty = isValuesEmpty, Values = valueList ?? new List<string>() };
var result = connection.Query<dynamic>(sql, parameters);

当valueList为null或空时,@IsValuesEmpty为1,返回所有数据;非空时则走IN条件,Dapper能正常重写IN部分的语句。

方案二:利用SQL的集合存在性判断

通过判断集合是否为空替代NULL检查,结合EXISTS语句:

List<string> valueList = new List<string> { "20230626", "20230808"};
var safeValues = valueList ?? new List<string>();
string sql = @"SELECT * FROM MyTable 
               WHERE EXISTS (SELECT 1 FROM @Values v WHERE v = MyTable.Value) 
                  OR (SELECT COUNT(*) FROM @Values) = 0";
var result = connection.Query<dynamic>(sql, new { Values = safeValues });

Dapper会将@Values重写为参数列表,SELECT COUNT(*) FROM @Values会计算参数数量,为空集合时返回0,从而匹配所有数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:23:09