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

如何使用SplitOn与Types映射Dapper中的复杂对象(Pessoa与Endereco)

使用Dapper返回包含关联Endereco的Pessoa列表解决方案

我来帮你完善这个方法,其实你已经找对了方向——用SplitOn和多类型映射来处理关联对象,只是细节上需要调整一下,下面一步步来:

先对齐实体类与数据库字段映射

你的实体类属性和数据库字段名存在一些不匹配的情况,比如Pessoa的emailAdress对应SQL里的P.Email,tipoPessoa对应P.IdTipoPessoa,Endereco的logradouro对应E.Rua,我们可以通过SQL别名来让它们精准匹配:

调整后的SQL查询语句

SELECT 
    P.Id,
    P.Nome as nome,
    P.SobreNome as sobreNome,
    P.Email as emailAdress,
    P.IdTipoPessoa as tipoPessoa,
    -- 分割标记:从这里开始是Endereco的字段
    E.Id as id,
    E.Cep as cep,
    E.Rua as logradouro,
    E.Bairro as bairro,
    E.Cidade as cidade,
    E.Complemento as complemento
FROM Pessoa P
INNER JOIN PessoaEndereco PE on P.Id = PE.IdPessoa
INNER JOIN Endereco E on PE.IdEndereco = E.Id

完善后的Dapper查询方法

接下来要使用Dapper的多类型Query重载,它专门用来处理一对关联对象的映射,同时正确设置SplitOn参数:

public IEnumerable<Pessoa> List()
{
    var QUERY = @"SELECT 
                    P.Id,
                    P.Nome as nome,
                    P.SobreNome as sobreNome,
                    P.Email as emailAdress,
                    P.IdTipoPessoa as tipoPessoa,
                    E.Id as id,
                    E.Cep as cep,
                    E.Rua as logradouro,
                    E.Bairro as bairro,
                    E.Cidade as cidade,
                    E.Complemento as complemento
                  FROM Pessoa P
                  INNER JOIN PessoaEndereco PE on P.Id = PE.IdPessoa
                  INNER JOIN Endereco E on PE.IdEndereco = E.Id ";

    using (var conexao = new SqlConnection(strConexao))
    {
        // 多类型Query重载:指定主实体Pessoa、关联实体Endereco,最终返回组装好的Pessoa
        return conexao.Query<Pessoa, Endereco, Pessoa>(
            sql: QUERY,
            map: (pessoa, endereco) => 
            {
                // 将关联的Endereco实例赋值给Pessoa的endereco属性
                pessoa.endereco = endereco;
                return pessoa;
            },
            splitOn: "id" // 告诉Dapper:从E.Id这个字段开始,后面的列映射到Endereco实体
        );
    }
}

核心逻辑说明

  • 多类型Query重载:Query<TFirst, TSecond, TResult>是Dapper为一对关联对象设计的专属API,它会自动把查询结果的每一行拆分成两个实体实例,再通过你提供的map委托完成关联组装。
  • SplitOn参数:这个参数的作用是标记实体映射的分割点,我们指定"id"是因为它是Endereco实体在SQL结果中的第一个字段,Dapper会自动把该字段之前的列映射到Pessoa,之后的列映射到Endereco。
  • 字段匹配:通过SQL别名让数据库字段和实体属性名完全对应,避免Dapper因名称不匹配导致的映射失败(Dapper默认大小写不敏感,但名称完全一致更稳妥)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:04:40