Dapper本身不直接解析或处理SQL Server的
FOR JSON PATH结果,但它能高效地将这类查询返回的JSON字符串作为普通字段读取——关键在于让SQL Server生成JSON,Dapper只负责“原样拿回来”,不额外序列化,避免双重JSON化或性能浪费。
明确职责分工:SQL Server做JSON生成,Dapper做轻量映射
SQL Server 2016+ 支持
FOR JSON PATH,可直接在查询中把结果集转成JSON字符串。Dapper只需用
string或
SqlDbType.NVarChar类型接收该列,无需引用
Newtonsoft.Json或
System.Text.Json去再序列化。 ✅ 正确做法:查询返回
SELECT Name, (SELECT Id, Title FROM Posts WHERE UserId = U.Id FOR JSON PATH) AS PostsJson FROM Users U,映射到
class User { public string Name { get; set; } public string PostsJson { get; set; } }
❌ 错误做法:用Dapper查出对象列表后再用JsonSerializer.Serialize()转JSON——这绕过了SQL Server的优化,还多一次内存分配和序列化开销
注意NULL和空集合的JSON表现
FOR JSON PATH默认对空子查询返回
NULL(不是
[]),若需空数组,得显式处理: 用
ISNULL((SELECT ... FOR JSON PATH), '[]')确保返回字符串
"[]"或用
COALESCE((SELECT ... FOR JSON PATH), '[]')Dapper读到的就是标准JSON字符串,后续可用
JsonDocument.Parse()或
JsonSerializer.Deserialize<t>()</t>按需解析
大结果集场景:流式读取 + 避免全量加载
若
FOR JSON PATH生成的JSON很大(如导出报表),别用
Query<t>()</t>一次性加载全部。改用
QueryMultiple()或
ExecuteReader()配合
SqlDataReader.GetFieldValue<string>(index)</string>,逐行读取JSON字符串,再流式写入响应或文件。 减少内存峰值,尤其适合Web API返回大型JSON文档 Dapper的
QueryFirstAsync<string>()</string>也适用——只取首行JSON字段,不构建对象列表
与Dapper.Extensions或Dapper.Contrib无关
FOR JSON PATH是纯SQL能力,不依赖任何Dapper扩展库。不需要引入
DapperExtensions或
Dapper.Contrib,也不需要配置
JsonConverter。保持Dapper轻量本质:它就是
IDbConnection的扩展,只管执行SQL、读取结果。
基本上就这些。核心就一条:让SQL Server吐JSON,Dapper当管道,不加工、不拦截、不重造轮子。
