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

将Dapper查询结果映射到类时,复杂类型属性值为空

解决Dapper嵌套对象反序列化时Range属性为null的问题

问题原因

Dapper默认不会自动将单结果集中的平级列映射到嵌套对象(比如A类里的Range属性),除非列名符合特定规则,或者手动指定映射逻辑。你当前存储过程返回的列名Start、End,Dapper无法关联到A.Range下的对应属性,因此Range始终为null。

解决方案

方案一:修改存储过程的列别名(推荐)

给嵌套对象的属性列加上前缀,格式为嵌套属性名_子属性名,让Dapper自动识别嵌套映射:

CREATE OR ALTER PROCEDURE [GetRecordsForA]
AS
BEGIN
    SELECT
        a.[Id],
        a.[Name],
        a.[StartDate] AS [Range_Start],
        a.[EndDate] AS [Range_End]
    FROM
        [A] a
END

修改后,Dapper会自动将Range_Start映射到A.Range.Start,Range_End映射到A.Range.End,无需改动C#代码。

方案二:手动映射结果(无需修改存储过程)

如果不能修改存储过程,可以通过手动处理查询结果来完成映射:

var dynamicResults = await connection.QueryAsync(commandDefinition);
var results = dynamicResults.Select(d => new A
{
    Id = d.Id,
    Name = d.Name,
    Range = new B
    {
        Start = d.Start,
        End = d.End
    }
}).ToList();

方案三:使用Dapper多类型映射

利用Dapper的多类型查询重载,指定拆分点来映射嵌套对象:

var results = await connection.QueryAsync<A, B, A>(
    commandDefinition,
    (aInstance, bInstance) =>
    {
        aInstance.Range = bInstance;
        return aInstance;
    },
    splitOn: "Start" // 指定从Start列开始映射到B类
);

注意:需确保存储结果集中,属于B类的列(Start、End)连续排列在拆分点之后,建议调整存储过程的列顺序为Id, Name, Start, End,避免属性映射混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:32:39