使用Dapper多映射QueryAsync时,对象B部分字段未映射的问题排查
问题分析与解决方法
你的问题核心在于Dapper多映射的字段顺序和splitOn参数配置错误,导致B对象的非首字段无法被正确映射。以下是具体的排查和修复步骤:
1. 明确Dapper多映射的核心规则
当使用QueryAsync<T1, T2, T3, TResult>时,Dapper的映射逻辑是:
- 严格按照泛型参数顺序(
A → B → C)依次映射查询结果的字段 splitOn参数用于指定下一个对象的起始字段名,多个分割点用逗号分隔。比如第一个分割点是B对象的第一个字段,第二个是C对象的第一个字段。
你的原有实现完全违背了这个规则,导致B对象只有第一个字段被映射,其余字段被忽略。
2. 修复SQL查询的字段顺序
必须将查询结果的字段按照A的字段 → B的字段 → C的字段的顺序排列,确保Dapper能按顺序分配到对应的对象:
"SELECT A.CodePlan, A.CodePlanNum, -- A类需要的所有字段 B.CodePlanNum, B.RegleGroupeGarantieLiee, -- B类需要的所有字段 C.CodePlanCouverture, C.TypeAlis, C.AgeMaxEmission, C.CodePlanGarantieLiee -- C类需要的所有字段 FROM {nameof(C)} JOIN {nameof(A)} ON {nameof(A)}.CodePlan = {nameof(C)}.CodePlanCouverture JOIN {nameof(B)} ON {nameof(B)}.CodePlanNum = {nameof(A)}.CodePlanNum WHERE {predicate}"
注意:修正了你原有SQL中的语法错误
{B)},改为{nameof(B)}。
3. 正确配置splitOn参数
splitOn只需要指定B对象的第一个字段和C对象的第一个字段即可,告诉Dapper从哪个字段开始切换到下一个对象的映射:
var queryReturn = (await connection.QueryAsync<A, B, C, Result>( query, (a, b, c) => map.BuildResultQueryReturn(a, b, c), splitOn: $"{nameof(B.CodePlanNum)},{nameof(C.CodePlanCouverture)}") ).ToList();
4. 额外验证点
- 确认B类的
RegleGroupeGarantieLiee属性类型与数据库字段匹配:SQL Server的smallint对应C#的short类型,如果属性是int也能自动转换,但建议保持类型一致避免潜在问题。 - 确认B类属性名与数据库字段名完全匹配(Dapper默认按名称匹配,大小写不敏感),如果不一致可以用
[Column]特性显式映射。
内容的提问来源于stack exchange,提问作者Nice Kloe
相关产品推荐
相关产品推荐

