AutoMapper:将扁平对象列表映射为复杂对象的实现方案咨询
解决.NET 6中AutoMapper合并同用户多条记录为带地址列表对象的问题
核心思路
要实现将同一用户的多条UserDetailDto记录合并为单个UserDetail对象并聚合地址列表,需先对源数据按用户ID分组,再结合AutoMapper完成基础信息与地址列表的映射。
步骤实现
1. 补充AutoMapper映射配置
首先添加UserDetailDto到UserAddress的映射,用于将每条Dto中的地址字段转换为UserAddress对象:
CreateMap<UserDetailDto, UserAddress>();
原有UserDetailDto到UserDetail的映射可保留(基础字段可直接映射):
CreateMap<UserDetailDto, UserDetail>() .ForMember(dest => dest.ID, src => src.MapFrom(_ => _.ID)) .ForMember(dest => dest.FirstName, src => src.MapFrom(_ => _.FirstName)) .ForMember(dest => dest.LastName, src => src.MapFrom(_ => _.LastName));
2. 实现合并映射的两种方式
方式一:手动分组+映射(简单直接)
先对源Dto列表按用户ID分组,再逐个构建UserDetail对象:
// userDetailDtos为从数据库获取的源数据列表 var groupedUserDtos = userDetailDtos.GroupBy(dto => dto.ID); var userDetails = new List<UserDetail>(); foreach (var userGroup in groupedUserDtos) { // 取组内第一条Dto映射用户基础信息 var userDetail = _mapper.Map<UserDetail>(userGroup.First()); // 将组内所有Dto映射为地址列表 userDetail.Addresses = _mapper.Map<List<UserAddress>>(userGroup.ToList()); userDetails.Add(userDetail); }
方式二:自定义AutoMapper类型转换器(更优雅)
创建自定义转换器处理列表到列表的转换逻辑,让AutoMapper自动完成分组和合并:
public class UserDetailDtoListConverter : ITypeConverter<List<UserDetailDto>, List<UserDetail>> { private readonly IMapper _mapper; public UserDetailDtoListConverter(IMapper mapper) { _mapper = mapper; } public List<UserDetail> Convert(List<UserDetailDto> source, List<UserDetail> destination, ResolutionContext context) { var result = new List<UserDetail>(); var groupedUsers = source.GroupBy(dto => dto.ID); foreach (var group in groupedUsers) { var user = _mapper.Map<UserDetail>(group.First()); user.Addresses = _mapper.Map<List<UserAddress>>(group); result.Add(user); } return result; } }
在AutoMapper配置中注册该转换器:
CreateMap<List<UserDetailDto>, List<UserDetail>>() .ConvertUsing<UserDetailDtoListConverter>();
之后直接调用AutoMapper映射方法即可完成转换:
var userDetails = _mapper.Map<List<UserDetail>>(userDetailDtos);
注意事项
- 需确保数据库中同一ID的用户基础信息(FirstName、LastName)完全一致,若存在不一致需额外处理冲突(如取第一条、最新记录等)。
- 若地址字段可能为空,AutoMapper会自动处理为
null或空列表,可根据需求在映射配置中添加NullSubstitute设置默认值。
内容的提问来源于stack exchange,提问作者Reyan Chougle
相关产品推荐
相关产品推荐

