如何规避Dapper GridReader的"No columns were selected"异常
解决方案:手动处理DbDataReader而非依赖GridReader
因为Dapper的GridReader并未公开内部的DbDataReader,无法直接访问HasRows,你可以绕过QueryMultipleAsync,手动创建并执行SqlCommand,直接操作DbDataReader来判断结果集状态,同时保留Dapper的对象映射能力:
// 1. 创建并配置命令对象 using var command = new SqlCommand(query, SqlConnection); command.CommandType = CommandType.StoredProcedure; // 添加参数(需根据你的实际参数集合类型调整) foreach (var param in parameters) { var sqlParam = command.Parameters.Add(param); // 标记OUTPUT参数,需匹配你的存储过程参数定义 if (sqlParam.Direction == ParameterDirection.Output || sqlParam.Direction == ParameterDirection.InputOutput) { // 保持参数方向设置,无需额外操作 } } // 2. 执行读取器 using var reader = await command.ExecuteReaderAsync(); // 3. 判断是否有可用结果集并映射 IEnumerable<resultDb> results = Enumerable.Empty<resultDb>(); if (reader.HasRows && reader.FieldCount > 0) { // 用Dapper内置映射方法完成对象转换 results = SqlMapper.Map<resultDb>(reader, parameters, null, buffered: true); } // 4. 处理OUTPUT参数(需读取器关闭或切换到下一个结果集后才能获取值) await reader.NextResultAsync(); // 若有多个结果集按需调用,仅处理OUTPUT参数可直接关闭 reader.Close(); foreach (SqlParameter sqlParam in command.Parameters) { if (sqlParam.Direction is ParameterDirection.Output or ParameterDirection.InputOutput) { var outputValue = sqlParam.Value; // 这里处理输出参数的值 } }
方案优势
- 直接通过
DbDataReader.HasRows和FieldCount判断结果集状态,完全避免触发Dapper的无列选择异常 - 依然复用Dapper的
SqlMapper.Map方法完成对象映射,无需手动编写映射逻辑 - 手动控制OUTPUT参数的读取,不受
GridReader.IsConsumed的状态限制
内容的提问来源于stack exchange,提问作者noontz
相关产品推荐
相关产品推荐

