使用AutoMapper的IMemberValueResolver时TDestMember始终为0或null,求解决思路
我来帮你拆解一下这个问题,结合你的代码来看,主要有这几个关键原因:
目标成员初始化时机导致的默认值
AutoMapper在执行映射时,会先创建目标对象(如果是全新实例的话),对于值类型(比如你的int类型SortOrder),默认初始值就是0;如果是引用类型则是null。而IMemberValueResolver的destinationMember参数,传递的是解析器执行前目标成员的当前值——如果是新对象,自然就是类型默认值了。对
IMemberValueResolver参数的误解
你可能以为destinationMember会是你期望最终赋予目标成员的值,但实际上它的作用是让你能基于目标对象的现有值做逻辑处理(比如更新已有对象时,结合旧值计算新值)。在你的代码场景里,看起来是在映射新对象,所以这个参数自然就是0,这是完全正常的行为,不是bug。你的调用方式并未传递目标现有值
看你的调用代码:.ForMember(dest => dest.SortOrder, opt => opt.ResolveUsing<CustomResolver, int>(src => src.Id));这里你指定了源成员是
src.Id,所以sourceMember会拿到Id的值,但destinationMember依然是目标SortOrder的初始值,因为此时AutoMapper还没给这个成员赋值,解析器是赋值前被调用的。
额外说明
如果你的解析器逻辑不需要依赖目标成员的现有值,那完全可以忽略destinationMember参数——就像你现在的代码直接返回1,这个参数不影响最终结果。如果确实需要用到目标的现有值,那要确保你是在更新已有目标对象的场景下调用映射(比如用Mapper.Map(source, existingDestination)),这时候destinationMember才会是现有对象的SortOrder值。
内容的提问来源于stack exchange,提问作者user2270653

