如何将领域模型与DTO绑定映射,按ID查询返回单个ConceptManagementDto
嵌套集合字段的映射实现
手动映射(零第三方依赖场景)
你代码中ConceptSubSidiary字段本质是领域模型中导航属性conceptSubSidiaries的逐字段投影转换,可以直接通过LINQ的Select方法完成子项的类型转换,补全后的完整代码如下:
public async Task<ConceptManagementDto> GetConceptById(Guid id) { var concept = await _conceptManagementRepository.Query() .Include(x => x.conceptSubSidiaries) .GetOneAsync(x => x.Id == id); // 空值保护,避免查询无结果时触发空引用异常 if (concept == null) { return default; } return new ConceptManagementDto { ConceptManagementId = concept.Id, ConceptName = concept.ConceptName, ConceptLatinName = concept.ConceptLatinName, // 逐个子项完成领域模型到DTO的转换 ConceptSubSidiary = concept.conceptSubSidiaries? .Select(sub => new ConceptSubDto { // 按字段实际对应关系赋值 ConceptSubId = sub.Id, ConceptSubName = sub.SubName }) // 兜底空集合,避免前端收到null值增加兼容成本 .ToList() ?? new List<ConceptSubDto>() }; }
映射组件简化方案(项目已集成AutoMapper/Mapster场景)
如果项目已经引入了约定式对象映射工具,不需要逐字段手动赋值,只需提前注册好类型映射规则即可:
- 注册映射规则(应用层启动时执行一次即可)
// 以AutoMapper为例 CreateMap<Domain.ConceptManagement, ConceptManagementDto>() .ForMember(dest => dest.ConceptManagementId, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.ConceptSubSidiary, opt => opt.MapFrom(src => src.conceptSubSidiaries)); CreateMap<Domain.ConceptSubsidiary, ConceptSubDto>() .ForMember(dest => dest.ConceptSubId, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.ConceptSubName, opt => opt.MapFrom(src => src.SubName));
- 业务方法中直接调用映射方法即可,嵌套集合会自动完成转换:
public async Task<ConceptManagementDto> GetConceptById(Guid id) { var concept = await _conceptManagementRepository.Query() .Include(x => x.conceptSubSidiaries) .GetOneAsync(x => x.Id == id); return _mapper.Map<ConceptManagementDto>(concept); }
注意事项
- 查询时必须显式
Include导航子集合,否则EF Core会默认将子集合设为null,最终DTO中的子列表会无值 - 字段名不匹配时,需要在映射配置中显式声明源字段和目标字段的对应关系,避免出现赋值为null的问题
- 集合类型字段建议增加空值兜底逻辑,不要直接将可能为null的集合返回给前端
内容的提问来源于stack exchange,提问作者NeonX
相关产品推荐
相关产品推荐

