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

来源:这里教程网 时间:2026-02-21 17:37:39 作者:

Dapper 的

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

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

调用

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

示例:查询用户列表 + 订单总数 + 最新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;";
<p>using var conn = new SqlConnection(connStr);
var multi = conn.QueryMultiple(sql, new { status = "Active" });</p><p>var users = multi.Read<User>().ToList();           // 第一个结果集 → User 列表
var orderCount = multi.ReadSingle<int>();          // 第二个结果集 → 单个 int 值
var recentOrders = multi.Read<Order>().ToList();   // 第三个结果集 → Order 列表

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

SQL Server 存储过程中用多个

SELECT
返回不同结构的数据时,
QueryMultiple
是最佳选择。

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

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

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

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

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

除了

Read<t>()</t>
GridReader
还提供常用快捷方法:

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

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

相关推荐