AutoMapper映射Tuple多源对象时如何无需逐个指定同名字段映射规则?
完全可以实现你想要的简化配置,这里提供两种常用的实现方案:
方案1:无需使用Tuple,使用AutoMapper原生多实例映射(最推荐)
AutoMapper本身支持将多个源对象依次映射到同一个目标实例,你只需要分别配置两个单源到目标的映射即可,同名字段会自动匹配:
public class UsernameWithTodoTitleMappingProfile : Profile { public UsernameWithTodoTitleMappingProfile() { // User到目标的同名字段自动匹配,无需额外配置 CreateMap<User, UsernameWithTodoTitle>(); // Todo到目标只需要单独配置不匹配的字段 CreateMap<Todo, UsernameWithTodoTitle>() .ForMember(dest => dest.TodoTitle, opt => opt.MapFrom(src => src.Title)); } }
使用时依次调用映射即可:
// 先将User映射为目标实例 var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>(user); // 再将Todo的字段映射到已有目标实例 _mapper.Map(todo, usernameWithTodoTitle);
注意:如果User和Todo存在同名字段,后执行的Map操作会覆盖先执行的映射结果,按需调整映射顺序即可。
方案2:保留Tuple传参,使用IncludeMembers实现自动匹配
如果你需要保持现有传参方式(把两个对象打包为Tuple传参),可以通过IncludeMembers方法让AutoMapper自动扫描Tuple内的子对象匹配同名字段:
public class UsernameWithTodoTitleMappingProfile : Profile { public UsernameWithTodoTitleMappingProfile() { // 配置Tuple到目标的映射,指定从Tuple的两个子成员中自动匹配同名字段 CreateMap<(User User, Todo Todo), UsernameWithTodoTitle>() .IncludeMembers(src => src.User, src => src.Todo) // 仅单独配置不匹配的TodoTitle字段 .ForMember(dest => dest.TodoTitle, opt => opt.MapFrom(src => src.Todo.Title)); // IncludeMembers依赖基础单源映射配置 CreateMap<User, UsernameWithTodoTitle>(); CreateMap<Todo, UsernameWithTodoTitle>(); } }
使用方式和你之前的写法完全一致:
var usernameWithTodoTitle = _mapper.Map<UsernameWithTodoTitle>((user, todo));
这里给Tuple元素命名是为了提升代码可读性,你也可以继续使用默认的Item1/Item2写法,功能不受影响。
内容的提问来源于stack exchange,提问作者Question3r
相关产品推荐
相关产品推荐

