将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
相关产品推荐
相关产品推荐

