全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Dapper查询结果怎么映射到嵌套对象 Dapper复杂对象映射技巧

Dapper不支持全自动深度嵌套映射,但可通过Multi-Mapping(如Query配合splitOn)实现一对一级联;一对多用QueryMultiple分步查询+内存关联;三层及以上需组合多步查询并手动组装,核心是显式控制、避免N+1、注意别名与空值处理。

Dapper 本身不支持全自动的深度嵌套对象映射(比如 User 包含 AddressAddress 又包含 City),但通过组合使用 Query 的多映射(Multi-Mapping)和手动组装逻辑,完全可以优雅地实现嵌套对象填充。

用 Query 做两级关联映射

这是最常用、最清晰的方式,适用于主从结构(如 Order → OrderItem,User → Profile)。关键在于 SQL 中用 JOIN 拉平数据,并用 splitOn 参数告诉 Dapper 从哪一列开始是第二个对象的字段。

示例:映射 User 及其关联的 Department

var sql = @"
    SELECT u.Id, u.Name, u.Email, 
           d.Id as DeptId, d.Name as DeptName, d.Code
    FROM Users u
    LEFT JOIN Departments d ON u.DeptId = d.Id";

var users = connection.Query( sql, (user, dept) => { user.Department = dept; // 手动赋值 return user; }, splitOn: "DeptId" ).ToList();

  • splitOn 必须匹配第二对象的第一个非空列名(这里用 d.Id as DeptId,所以写 "DeptId"
  • 两个对象字段名可以不同,但别名要和 C# 属性名一致(或开启 SqlMapper.AddTypeMap 自定义映射)
  • lambda 中返回的是最终结果类型(这里是 User),可在此完成任意组装逻辑

处理一对多(如 User → List):用 QueryMultiple 分步查询

一对多不能靠单条 JOIN 搞定(会产生笛卡尔积),推荐用 QueryMultiple 执行多个语句,再在内存中关联。

var sql = @"
    SELECT * FROM Users WHERE IsActive = 1;
    SELECT u.Id as UserId, p.* FROM Posts p
    INNER JOIN Users u ON p.UserId = u.Id
    WHERE u.IsActive = 1;";

using var multi = connection.QueryMultiple(sql); var users = multi.Read().ToList(); var posts = multi.Read().ToList();

// 手动按 UserId 分组挂载 var lookup = posts.GroupBy(p => p.UserId).ToDictionary(g => g.Key, g => g.ToList()); foreach (var user in users) { user.Posts = lookup.GetValueOrDefault(user.Id, new List()); }

  • SQL 用分号分隔多个查询,Dapper 按顺序执行并返回多个结果集
  • 先查主表,再查子表,避免重复加载和 N+1 问题
  • Dictionary> 做 O(1) 关联,比循环嵌套查找快得多

三层及以上嵌套(如 User → Department → Company):组合 + 手动构建

没有内置三元映射,但可以拆解为两步:先用 Query 得到带 Department 的用户,再单独查 Company 并批量挂载。

// 第一步:查 User + Department(同上)
var usersWithDepts = connection.Query(...).ToList();

// 第二步:提取所有 DeptId,批量查 Company var deptIds = usersWithDepts .Where(u => u.Department != null) .Select(u => u.Department.Id) .Distinct() .ToArray();

if (deptIds.Length > 0) { var companies = connection.Query( "SELECT * FROM Companies WHERE Id IN @ids", new { ids = deptIds } ).ToDictionary(c => c.Id);

foreach (var user in usersWithDepts)
{
    if (user.Department != null && companies.TryGetValue(user.Department.Id, out var company))
    {
        user.Department.Company = company;
    }
}

}

  • 避免为每个 Department 单独查 Company(N+1)
  • 利用 ToDictionary 实现快速反查,保持线性时间复杂度
  • 注意空值判断,防止 NullReferenceException

小技巧:用匿名对象或 ValueTuple 简化中间步骤

当嵌套层级多、临时组装频繁时,可用匿名类型过渡,让代码更松耦合:

var result = connection.Query(
    sql,
    (u, d, c) => (u, d, c),
    splitOn: "DeptId,CompanyId"
).ToList();

// 再统一组装成最终对象 var finalUsers = result.Select(x => { x.Item1.Department = x.Item2; x.Item2.Company = x.Item3; return x.Item1; }).ToList();

  • 适合一次性复杂映射,不想提前定义中间 DTO 类
  • ValueTuple(C# 7+)比匿名类更轻量,且可序列化
  • 仍需明确指定 splitOn 字段名,顺序必须与泛型参数一致

基本上就这些。Dapper 的哲学是“显式优于隐式”,它不隐藏 SQL 和映射逻辑,反而让你对性能和行为有完全掌控。嵌套映射不复杂,但容易忽略 splitOn 的大小写、别名一致性、空值处理这些细节。


# app  # ai  # c#  # sql  # int  # 循环  # Lambda  # 泛型  # 对象  # 多个  # 笛卡尔  # 不支持  # 的是  # 这是  # 字段名  # 让你  # 第一个  # 在此  # 适用于 


相关文章: 建站主机SSH密钥生成步骤及常见问题解答?  如何通过VPS搭建网站快速盈利?  ,网页ppt怎么弄成自己的ppt?  设计网站制作公司有哪些,制作网页教程?  如何实现建站之星域名转发设置?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  黑客如何通过漏洞一步步攻陷网站服务器?  建站之星导航菜单设置与功能模块配置全攻略  宝华建站服务条款解析:五站合一功能与SEO优化设置指南  香港服务器租用费用高吗?如何避免常见误区?  网站制作网站,深圳做网站哪家比较好?  网站制作知乎推荐,想做自己的网站用什么工具比较好?  专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?  建站之星价格显示格式升级,你的预算足够吗?  音乐网站服务器如何优化API响应速度?  linux top下的 minerd 木马清除方法  免费制作小说封面的网站有哪些,怎么接网站批量的封面单?  如何选择美橙互联多站合一建站方案?  建站主机类型有哪些?如何正确选型  再谈Python中的字符串与字符编码(推荐)  建站主机选哪种环境更利于SEO优化?  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  如何通过WDCP绑定主域名及创建子域名站点?  如何在西部数码注册域名并快速搭建网站?  建站主机选购指南与交易推荐:核心配置解析  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  如何通过.red域名打造高辨识度品牌网站?  如何制作算命网站,怎么注册算命网站?  ,有什么在线背英语单词效率比较高的网站?  建站之星如何实现PC+手机+微信网站五合一建站?  建站OpenVZ教程与优化策略:配置指南与性能提升  中山网站推广排名,中山信息港登录入口?  黑客入侵网站服务器的常见手法有哪些?  如何在阿里云ECS服务器部署织梦CMS网站?  C#如何序列化对象为XML XmlSerializer用法  c# 在ASP.NET Core中管理和取消后台任务  如何选择可靠的免备案建站服务器?  宝塔建站助手安装配置与建站模板使用全流程解析  如何在Windows虚拟主机上快速搭建网站?  巅云智能建站系统:可视化拖拽+多端适配+免费模板一键生成  如何快速搭建高效可靠的建站解决方案?  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  建站主机如何选?性能与价格怎样平衡?  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  建站之星logo尺寸如何设置最合适?  建站之星在线版空间:自助建站+智能模板一键生成方案  如何在阿里云香港服务器快速搭建网站?  如何安全更换建站之星模板并保留数据?  微信h5制作网站有哪些,免费微信H5页面制作工具?  公司网站制作需要多少钱,找人做公司网站需要多少钱? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。