buffered 是 Dapper 中控制查询结果加载方式的核心参数,它决定数据是从数据库一次性读入内存(缓冲),还是边读边处理(非缓冲)。
buffered = true(默认缓冲模式)
这是 Dapper 的默认行为。查询执行后,Dapper 会把**全部结果集一次性从数据库读取到内存**,构造成 List、IEnumerable 等完整集合,再返回给调用方。
适合中小数据量(比如几千条以内),代码简洁,可多次遍历结果
支持对结果做 Count()、ToList()、Skip().Take() 等操作
内存占用与结果集大小成正比,百万级数据容易触发 OutOfMemoryException
buffered = false(非缓冲 / 流式模式)
启用该模式后,Dapper 不会预加载全部数据,而是打开一个“活”的数据库游标,**按需逐行读取、映射并返回**。枚举时才真正从数据库拉取下一条记录。
内存占用极低,稳定处理千万级数据也不爆内存
结果只能被**遍历一次**(本质是 IEnumerator),不能反复使用或缓存整个集合
适合导出、ETL、分批处理、日志分析等流式场景
必须确保在使用完前连接未关闭(建议配合 using 或异步流式 API)
怎么设置 buffered 参数
可通过 CommandFlags 显式控制:
Query(sql, flags: CommandFlags.Buffered) —— 显式启用缓冲(等同于默认)
Query(sql, flags: CommandFlags.None) —— 显式禁用缓冲(即流式)
也可传入 buffered: false(部分重载支持布尔参数)
选哪个?关键看场景
要查几十条配置、用户列表 → 用默认 buffered=true,简单可靠
要导出 500 万订单到 Excel → 必须用 buffered=false,避免内存崩掉
要做分页但数据量大 → 考虑服务端分页(加 OFFSET/LIMIT),而不是靠客户端 Skip/Take
基本上就这些。