ASP.NET Core使用AutoMapper映射如何保留目标对象原有未映射属性值
解决方案
- 调整映射调用方法
你当前的写法是让AutoMapper根据DTO新建了一个Exam实体,自然会丢失原有实体的未映射属性值。AutoMapper提供了映射到已有对象的重载方法,直接修改原有对象的属性即可,不需要生成新实例:
将Edit Action中的对应代码替换为:
// 原有查询逻辑不变 var exam = await _examRepository.GetByIdAsync(model.Id); // 替换原来的赋值写法,直接映射到已有exam对象 _mapper.Map(model, exam); // 后续审计、更新逻辑不变 exam.WriteEditingAudit(_appUser);
这个重载会自动把ExamEditVm中存在的属性值覆盖到已有exam对象上,所有ExamEditVm没有的属性,都会保留原有exam对象的取值。
- 可选:优化映射配置(提升安全性)
为了避免后续误映射不需要的属性,你可以在MappingProfile中显式配置反向映射的忽略规则,两种写法可选:- 写法一:批量自动忽略源对象不存在的目标属性
CreateMap<Exam, ExamEditVm>() .ReverseMap() // 仅校验源对象的成员是否有匹配,源中不存在的目标成员自动忽略 .ValidateMemberList(MemberList.Source);- 写法二:显式逐个忽略不需要映射的属性
适合需要更严格控制映射规则的场景:
CreateMap<Exam, ExamEditVm>() .ReverseMap() .ForMember(dest => dest.SchoolSubjectId, opt => opt.Ignore()) .ForMember(dest => dest.ProfId, opt => opt.Ignore()) .ForMember(dest => dest.Group, opt => opt.Ignore()) .ForMember(dest => dest.SchoolSubject, opt => opt.Ignore()) .ForMember(dest => dest.Prof, opt => opt.Ignore()) .ForMember(dest => dest.ExamMarks, opt => opt.Ignore()) .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) .ForMember(dest => dest.CreatedOn, opt => opt.Ignore()) .ForMember(dest => dest.IsEdited, opt => opt.Ignore()) .ForMember(dest => dest.LastEditor, opt => opt.Ignore()) .ForMember(dest => dest.LastEditDate, opt => opt.Ignore());
内容的提问来源于stack exchange,提问作者JOCKH
相关产品推荐
相关产品推荐

