DTO与实体映射配置
本文档引用的文件
/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameCreateOrUpdateDtoBase.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameCreateDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameUpdateDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Domain/MyEntityNames/MyEntityName.cs
目录
简介
本文说明MyEntityNameAutoMapperProfile中定义的AutoMapper配置规则,涵盖从MyEntityName实体到MyEntityNameDto的正向映射,以及从MyEntityNameCreateOrUpdateDtoBase到MyEntityName的反向映射。同时阐述了字段忽略、自定义转换、条件映射等高级特性的使用场景与实现方式,并解释如何确保审计信息等敏感字段的安全性。
核心映射配置
MyEntityNameAutoMapperProfile类继承自AutoMapper.Profile,在构造函数中通过CreateMap<TSource, TDestination>方法定义了类型之间的映射关系。该配置支持ABP框架的扩展属性(Extra Properties)和并发控制戳(Concurrency Stamp),确保数据完整性与可扩展性。
Section sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs
正向映射:实体到DTO
正向映射定义了从领域实体MyEntityName到数据传输对象MyEntityNameDto的转换规则。此映射通过CreateMap<MyEntityName, MyEntityNameDto>建立,并设置MemberList.None以允许映射所有公共成员。
映射过程中启用了MapExtraProperties选项,参数为MappingPropertyDefinitionChecks.None,表示在映射时包含ABP的扩展属性(如动态属性),且不进行属性定义检查,提升灵活性。
映射字段说明
Code: 编号字段,直接映射Name: 名称字段,直接映射Sort: 排序字段,直接映射Remark: 备注字段,直接映射IsDisabled: 是否禁用状态,可为空布尔值ConcurrencyStamp: 并发控制戳,用于乐观锁机制
Diagram sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Domain/MyEntityNames/MyEntityName.cs
Section sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameDto.cs
反向映射:DTO到实体
反向映射通过基类MyEntityNameCreateOrUpdateDtoBase实现,该基类被MyEntityNameCreateDto和MyEntityNameUpdateDto继承。虽然当前配置未显式定义反向映射,但可通过扩展CreateMap添加:
CreateMap<MyEntityNameCreateOrUpdateDtoBase, MyEntityName>()
.ForMember(dest => dest.Id, opt => opt.Ignore()) // 创建时不映射Id
.ForMember(dest => dest.CreationTime, opt => opt.Ignore())
.ForMember(dest => dest.CreatorId, opt => opt.Ignore())
.ForMember(dest => dest.LastModificationTime, opt => opt.Condition(src => src.Id != default))
.ForMember(dest => dest.LastModifierId, opt => opt.Condition(src => src.Id != default));
此类映射确保:
- 新建实体时忽略
Id、创建时间与创建人 - 更新时仅当
Id存在时才更新修改时间与修改人
Section sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameCreateOrUpdateDtoBase.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameCreateDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameUpdateDto.cs
高级映射特性
字段忽略(Ignore)
使用.ForMember(..., opt => opt.Ignore())可排除特定字段的映射。常用于:
- 实体生成字段(如
Id、CreationTime) - 只读属性
- 敏感信息(如密码、密钥)
自定义转换(Using)
通过.ConvertUsing<ConverterType>()或.Using()指定自定义转换逻辑,适用于:
- 枚举与字符串互转
- 时间格式化
- 加密/解密字段
条件映射(Condition)
使用.Condition()定义映射前提,例如:
.ForMember(dest => dest.LastModifierId, opt => opt.Condition(src => src.Id != default))
确保仅在更新操作时设置修改人信息。
Section sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs
分页结果的自动转换支持
ABP框架中的PagedResultDto<T>可自动与IQueryable<T>结合使用。当MyEntityNameDto完成正确映射后,可通过以下方式实现分页转换:
var query = await _repository.GetQueryableAsync();
var totalCount = await query.CountAsync();
var entities = await query.PageBy(input).ToListAsync();
var dtos = ObjectMapper.Map<List<MyEntityName>, List<MyEntityNameDto>>(entities);
return new PagedResultDto<MyEntityNameDto>(totalCount, dtos);
此模式无需额外配置即可实现分页结果的自动封装与映射。
Section sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs
敏感字段安全性处理
为保护审计字段(如创建/修改时间、用户ID)不被客户端篡改,应采取以下措施:
- 映射时忽略写入:在DTO到实体的映射中,使用
Ignore()排除CreationTime、CreatorId等字段 - 服务层赋值:在应用服务中通过
CurrentUser和Clock自动填充审计信息 - 验证并发戳:利用
ConcurrencyStamp防止并发修改冲突
Diagram sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application.Contracts/Dtos/MyEntityNames/MyEntityNameDto.cs/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs
映射错误调试方法
常见错误类型
- Missing Type Map Configuration: 未定义映射关系
- Unmapped Members: 存在未映射的成员
- Type Mismatch: 类型不匹配导致转换失败
调试步骤
- 启用详细异常:在开发环境中开启
Mapper.AssertConfigurationIsValid() - 检查未映射成员:使用
AssertConfigurationIsValid()验证配置完整性 - 日志记录:记录源对象与目标对象结构
- 单元测试:编写映射测试用例验证双向转换
Diagram sources
/lmes-template/src/CMS.Plugin.MyPluginName.Application/MapperProfiles/MyEntityNameAutoMapperProfile.cs
开发建议
- 分离映射配置:复杂系统中将不同模块的映射配置拆分为多个Profile类
- 统一命名规范:保持实体与DTO命名一致性,便于识别
- 避免循环引用:DTO设计时注意防止导航属性导致的序列化问题
- 性能优化:对高频调用接口使用
ProjectTo<T>()直接在数据库端投影 - 版本兼容:DTO变更时考虑向后兼容性,避免破坏现有API
结论
MyEntityNameAutoMapperProfile通过简洁的配置实现了实体与DTO之间的高效转换,结合ABP框架特性保障了扩展性与安全性。合理运用字段忽略、条件映射等高级功能,可有效控制数据流向,保护敏感信息。建议在开发过程中持续验证映射配置,并通过单元测试确保转换逻辑的正确性。