You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Dapper返回含Status、Client关联子对象的Job实体列表

Dapper 实现关联表查询填充导航属性方案

首先需要先修正你现有模型的一个问题,否则映射会失败:

  • JobModel的Id属性只有get访问器,是只读属性,Dapper无法给这个属性赋值,需要补充set访问器,可以用private set或者init限制外部修改权限,只要存在赋值入口就行。修正后代码:
public class JobModel
{
    public int Id { get; set; }
    public string Description { get; set; }
    public StatusModel Status { get; set; }
    public ClientModel Client { get; set; }
}

具体实现

Dapper原生自带多映射功能,不需要安装额外扩展包,直接用Query的多泛型重载就能实现关联对象填充,你写的联表SQL不需要改动,直接用就可以。
完整查询代码:

using var conn = new SqlConnection("你的数据库连接字符串");
var querySql = @"SELECT j.*, s.*, c.* 
                 FROM Job j 
                 INNER JOIN Status s ON j.StatusId = s.Id 
                 INNER JOIN Client c ON j.ClientId = c.Id;";

var result = conn.Query<JobModel, StatusModel, ClientModel, JobModel>(
    sql: querySql,
    map: (job, status, client) =>
    {
        job.Status = status;
        job.Client = client;
        return job;
    },
    splitOn: "Id,Id"
).ToList();

执行完成后result就是填充好Status和Client导航属性的JobModel列表。

关键参数说明

  • 泛型参数顺序:必须和你SELECT语句返回的表字段顺序一致,你当前SQL是先返回Job字段、再返回Status字段、最后返回Client字段,所以前三个泛型依次对应这三个模型,最后一个泛型是最终返回的主实体类型,也就是JobModel。
  • splitOn:用来标记Dapper切换映射实体的列名,因为三个表的主键都叫Id,所以按映射顺序,遇到第一个Id列(Status表主键)就开始映射StatusModel,遇到第二个Id列(Client表主键)就开始映射ClientModel,所以传"Id,Id"即可。如果后续关联表的主键名不是Id,替换成对应的列名就行。
  • 你的场景是Job单条记录对应单个Status、单个Client,联表结果不会出现重复的Job记录,不需要额外去重。如果是一对多场景(比如一个Job对应多条操作记录),用字典缓存已查询到的主实体去重就行。

内容的提问来源于stack exchange,提问作者Bazza Formez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 12:09:22