Dapper中QueryMultiple怎么用 Dapper返回多个结果集教程

11次阅读

Dapper的QueryMultiple方法可一次性执行含多个selectsql并按序获取多个结果集,返回GridReader对象,需严格按SQL中SELECT顺序调用Read()等方法读取,支持ReadSingle、Skip等进阶操作。

Dapper中QueryMultiple怎么用 Dapper返回多个结果集教程

Dapper 的 QueryMultiple 方法用于执行一条 SQL 语句(通常是存储过程或含多个 SELECT 的批处理),并一次性获取多个结果集,比多次调用 Query 更高效、更节省数据库连接资源。

基本用法:用 QueryMultiple 获取多个结果集

调用 QueryMultiple 后返回一个 SqlMapper.GridReader 对象,它支持按顺序读取每个结果集,每次调用 Read() 就消耗一个结果集。

示例:查询用户列表 + 订单总数 + 最新3个订单

string sql = @"     SELECT * FROM Users WHERE Status = @status;     SELECT count(*) FROM Orders WHERE UserId IN (SELECT Id FROM Users WHERE Status = @status);     SELECT TOP 3 * FROM Orders ORDER BY CreatedTime DESC;"; 

using var conn = new SqlConnection(connStr); var multi = conn.QueryMultiple(sql, new { status = "Active" });

var users = multi.Read().ToList(); // 第一个结果集 → User 列表 var orderCount = multi.ReadSingle(); // 第二个结果集 → 单个 int 值 var recentOrders = multi.Read().ToList(); // 第三个结果集 → Order 列表

常见场景:配合存储过程使用

SQL Server 存储过程中用多个 SELECT 返回不同结构的数据时,QueryMultiple 是最佳选择。

  • 确保每个 SELECT 的列名和类型与目标 .net 类型匹配(Dapper 按列名映射)
  • 避免在存储过程中使用 SET NOCOUNT ON —— 它会干扰 Dapper 解析结果集(除非你明确知道影响并做了适配)
  • 如果某结果集为空,Read() 仍会返回空集合(如 IEnumerable),不会报错

注意点:顺序必须严格匹配,不能跳过或乱序

GridReader 是“游标式”读取,结果集按 SQL 中 SELECT 出现的顺序依次消费,且不可回退、不可重复读。

  • 调用 Read() 一次,就向前推进一个结果集;跳过某个结果集会导致后续读取错位
  • 不要对同一个 GridReader 多次调用 Read() 读同一结果集(第二次会返回空)
  • 如果只想读前两个结果集,第三个不关心,也建议显式调用 multi.Read()multi.Skip()(Dapper v2+ 支持)来“跳过”,避免潜在异常

进阶技巧:泛型 ReadSingle / ReadFirstOrdefault / Skip

除了 Read()GridReader 还提供常用快捷方法:

  • ReadSingle():读取单值结果(如 SELECT COUNT(*)
  • ReadFirstOrDefault():读第一个对象,无数据时返回 default(T)
  • Skip()(Dapper ≥ 2.0):跳过当前结果集,适合忽略中间某个结果
  • IsConsumed 属性可检查是否所有结果集已被读完

基本上就这些。QueryMultiple 不复杂但容易忽略顺序和生命周期管理,用对了能显著简化多结果集场景的代码。

text=ZqhQzanResources