如何为LINQ GroupBy查询自定义C# AutoMapper映射规则?
解决方案:用AutoMapper实现分组映射
完全可以通过AutoMapper实现你要的分组合并效果,核心是配置分组对象(IGrouping)到DTO的映射,同时结合单个实体到子DTO的映射。以下是具体实现步骤:
1. 配置AutoMapper映射规则
创建一个AutoMapper Profile类,定义两组映射关系:
- 单个
CashOrder到DenominationDetailsDto的映射(处理面额字段) - 分组后的
IGrouping<Guid, CashOrder>到CashOrderDto的映射(处理订单公共字段+合并面额集合)
public class CashOrderMappingProfile : Profile { public CashOrderMappingProfile() { // 映射CashOrder到DenominationDetailsDto,处理字段名映射(NumberOrdered → NumberHeld) CreateMap<CashOrder, DenominationDetailsDto>() .ForMember(dest => dest.NumberHeld, opt => opt.MapFrom(src => src.NumberOrdered)); // 映射分组对象到CashOrderDto CreateMap<IGrouping<Guid, CashOrder>, CashOrderDto>() // 取分组中第一个元素的公共订单字段(同一订单Id的这些字段应业务一致) .ForMember(dest => dest.DateCreated, opt => opt.MapFrom(src => src.First().DateCreated)) .ForMember(dest => dest.DateFinalised, opt => opt.MapFrom(src => src.First().DateFinalised)) .ForMember(dest => dest.ReferenceNumber, opt => opt.MapFrom(src => src.First().ReferenceNumber)) // 将分组内所有CashOrder自动映射为DenominationDetails集合 .ForMember(dest => dest.DenominationDetails, opt => opt.MapFrom(src => src)); } }
2. 实际使用映射
在服务层中,先对仓储返回的CashOrder集合按Id分组,再通过AutoMapper将分组结果映射为CashOrderDto集合:
// 假设已通过依赖注入获取IMapper实例 var rawOrders = _cashOrderRepository.GetFromStoredProcedure(); // 仓储返回的原始多条平级记录 var groupedOrders = rawOrders.GroupBy(order => order.Id); var cashOrderDtos = _mapper.Map<IEnumerable<CashOrderDto>>(groupedOrders); return cashOrderDtos.ToList();
关键说明
- 需保证同一订单Id的公共字段(
DateCreated、DateFinalised、ReferenceNumber)在原始数据中完全一致,因为我们使用First()取第一个元素的字段值,若业务上存在不一致会导致数据偏差。 - AutoMapper支持直接处理
IGrouping类型的映射,因为它继承了IEnumerable<CashOrder>,可自动将分组内的所有元素转换为DenominationDetails集合。
内容的提问来源于stack exchange,提问作者thespace
相关产品推荐
相关产品推荐

