Dapper不解析FOR JSON PATH结果,仅原样读取SQL Server生成的JSON字符串;应使用string类型接收,避免二次序列化,空集合需用ISNULL或COALESCE转为"[]",大数据量宜流式读取。

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按需解析()
大结果集场景:流式读取 + 避免全量加载
若FOR JSON PATH生成的JSON很大(如导出报表),别用Query一次性加载全部。改用QueryMultiple()或ExecuteReader()配合SqlDataReader.GetFieldValue,逐行读取JSON字符串,再流式写入响应或文件。
- 减少内存峰值,尤其适合Web API返回大型JSON文档
- Dapper的
QueryFirstAsync也适用——只取首行JSON字段,不构建对象列表()
与Dapper.Extensions或Dapper.Contrib无关
FOR JSON PATH是纯SQL能力,不依赖任何Dapper扩展库。不需要引入DapperExtensions或Dapper.Contrib,也不需要配置JsonConverter。保持Dapper轻量本质:它就是IDbConnection的扩展,只管执行SQL、读取结果。
基本上就这些。核心就一条:让SQL Server吐JSON,Dapper当管道,不加工、不拦截、不重造轮子。










