.NET 5 API中如何通过AutoMapper映射多对多表的IPv4属性至DTO
解决AutoMapper从多对多中间表映射额外属性的问题
你当前的映射逻辑只从UnitInst中提取了关联的Inst实体,完全没用到中间表的IPv4属性,这就是为什么InstDTO里的IPv4总是空的。下面给你两种可行的解决办法:
方案1:直接在投影中构造InstDTO
这种方式最直接,不需要额外的映射配置,直接在ForMember里手动构造InstDTO,同时从UnitInst中取IPv4和关联的Inst属性:
CreateMap<Unit, UnitDto>() .ForMember(dto => dto.Insts, opt => opt.MapFrom(x => x.UnitInsts.Select(y => new InstDTO { Id = y.Inst.Id, Name = y.Inst.Name, IPv4 = y.IPv4 }).ToList())) .PreserveReferences();
方案2:创建UnitInst到InstDTO的映射
如果希望映射逻辑更清晰、可维护,可以单独创建UnitInst到InstDTO的映射规则,再复用这个规则:
首先添加中间映射:
CreateMap<UnitInst, InstDTO>() .ForMember(dto => dto.Id, opt => opt.MapFrom(ui => ui.Inst.Id)) .ForMember(dto => dto.Name, opt => opt.MapFrom(ui => ui.Inst.Name)) .ForMember(dto => dto.IPv4, opt => opt.MapFrom(ui => ui.IPv4));
然后修改Unit到UnitDto的映射,直接把UnitInsts集合映射为InstDTO集合:
CreateMap<Unit, UnitDto>() .ForMember(dto => dto.Insts, opt => opt.MapFrom(x => x.UnitInsts.Select(ui => _mapper.Map<InstDTO>(ui)).ToList())) .PreserveReferences();
如果你使用的是AutoMapper的ProjectTo扩展(结合EF Core查询时更高效),也可以这样写:
CreateMap<Unit, UnitDto>() .ForMember(dto => dto.Insts, opt => opt.MapFrom(x => x.UnitInsts.ProjectTo<InstDTO>(_mapper.ConfigurationProvider))) .PreserveReferences();
关键注意事项
不管用哪种方案,一定要在EF查询中正确加载关联数据,否则会因为懒加载或者未加载关联实体导致Inst为null或者IPv4为空。你的查询代码应该包含Include和ThenInclude:
var units = _context.Units .Include(u => u.UnitInsts) .ThenInclude(ui => ui.Inst) .ToList(); var unitDtos = _mapper.Map<List<UnitDto>>(units);
这样才能确保UnitInsts以及关联的Inst实体都被完整加载,映射时能获取到所有需要的属性。
内容的提问来源于stack exchange,提问作者Alessandro Albi
相关产品推荐
相关产品推荐

