AutoMapper映射前编辑对象:为EmployeeSkill设置CreationTime值
解决AutoMapper映射时设置动态CreationTime的问题
要实现把EmployeeSkillDTO映射到EmployeeSkill时自动设置CreationTime为当前时间,你可以通过AutoMapper的ForMember方法定制字段映射规则,同时记得全局初始化AutoMapper配置(不要在业务逻辑里重复初始化),具体步骤如下:
1. 全局配置AutoMapper
首先把AutoMapper的配置放在应用启动的地方(比如ASP.NET Core的Program.cs,或者传统.NET的Global.asax),只需要初始化一次:
// 全局初始化示例(以Program.cs为例) Mapper.Initialize(cfg => { cfg.CreateMap<EmployeeSkillDTO, EmployeeSkill>() // 定制CreationTime的映射规则:忽略源值,直接返回当前时间 .ForMember(dest => dest.CreationTime, opt => opt.MapFrom(src => DateTime.Now)); });
这里要注意两个细节:
- 用
MapFrom而非UseValue:UseValue只会在配置初始化时取一次时间值,之后所有映射都会用同一个固定时间;而MapFrom每次映射都会执行委托,返回最新的当前时间,符合我们需要的动态效果。 - 如果想保留DTO中
CreationTime的非空值(仅当源值为null时才设置当前时间),可以调整规则为:.ForMember(dest => dest.CreationTime, opt => opt.MapFrom(src => src.CreationTime ?? DateTime.Now));
2. 业务逻辑中使用映射
修改你控制器里的代码,去掉重复的Mapper.Initialize调用,直接使用全局配置好的映射规则:
EmployeeSkill ski = context.EmployeeSkill .Where(r => r.SkillID == skill.SkillID && r.EmployeeID == skill.EmployeeID) .FirstOrDefault(); if (ski == null){ // 直接调用映射,AutoMapper会自动应用全局配置的规则 var map = Mapper.Map<EmployeeSkill>(skill); // 泛型参数可省略,AutoMapper会自动推断类型 context.EmployeeSkill.Add(map); // 别忘了保存上下文更改 context.SaveChanges(); }
为什么不推荐在业务逻辑里初始化AutoMapper?
你原来的代码把Mapper.Initialize放在if(ski == null)分支里,这样每次进入这个分支都会重新初始化AutoMapper,既会覆盖之前的配置,也会造成不必要的性能损耗,不符合AutoMapper的最佳实践。全局初始化一次就足够在整个应用中使用了。
另外,如果你使用的是AutoMapper的依赖注入版本(比如AutoMapper.Extensions.Microsoft.DependencyInjection),配置方式会更优雅,比如在Program.cs里:
builder.Services.AddAutoMapper(cfg => { cfg.CreateMap<EmployeeSkillDTO, EmployeeSkill>() .ForMember(dest => dest.CreationTime, opt => opt.MapFrom(src => DateTime.Now)); });
然后在控制器里注入IMapper接口来使用,这也是现代.NET应用的推荐方式。
内容的提问来源于stack exchange,提问作者Aya Abdelaziz
相关产品推荐
相关产品推荐

