如何在AutoMapper 12.0中以类名为前缀映射属性?
在AutoMapper 12.0中实现类名前缀主键的自动映射规则
AutoMapper 12.0移除了旧版的ForAllMaps方法,但可以通过Profile内的ForAllPropertyMaps或者全局自定义成员配置提供器来实现你需要的前缀主键映射规则,彻底替代重复的ForMember样板代码。
方案1:在单个Profile内配置全局规则
如果你的映射规则只需要在特定Profile生效,直接在Profile中使用ForAllPropertyMaps遍历所有属性映射,动态匹配规则:
public class EntityToViewModelMappingProfile : Profile { public EntityToViewModelMappingProfile() : base(nameof(EntityToViewModelMappingProfile)) { // 先配置所有实体与DTO的基础自动映射 CreateMap<Person, PersonDetails>().ReverseMap(); CreateMap<Order, OrderDetails>().ReverseMap(); // ...其他实体-DTO映射 // 正向映射:实体的[类名]Id → DTO的Id ForAllPropertyMaps(map => map.DestinationMember.Name.Equals("Id", StringComparison.OrdinalIgnoreCase) && map.SourceMember.Name.Equals($"{map.SourceType.Name}Id", StringComparison.OrdinalIgnoreCase), (map, config) => config.MapFrom(map.SourceMember.Name)); // 反向映射:DTO的Id → 实体的[类名]Id ForAllPropertyMaps(map => map.SourceMember.Name.Equals("Id", StringComparison.OrdinalIgnoreCase) && map.DestinationMember.Name.Equals($"{map.DestinationType.Name}Id", StringComparison.OrdinalIgnoreCase), (map, config) => config.MapFrom(map.SourceMember.Name)); } }
这段代码会自动匹配所有符合规则的属性:只要目标属性是Id、源属性是[源类名]Id,就自动建立映射;反向映射逻辑同理。
方案2:全局自定义约定(所有Profile生效)
如果希望这个规则应用到项目中所有的AutoMapper映射,可以创建一个自定义的IMemberConfigurationProvider:
1. 实现自定义成员配置提供器
public class PrefixIdConvention : IMemberConfigurationProvider { public void ApplyConfiguration(IMemberConfigurationExpression memberConfiguration) { // 正向映射:实体[类名]Id → DTO Id memberConfiguration.AddMemberMap() .ForDestinationMember(dest => dest.Name == "Id") .MapFrom(source => $"{source.Type.Name}Id"); // 反向映射:DTO Id → 实体[类名]Id memberConfiguration.AddMemberMap() .ForSourceMember(source => source.Name == "Id") .MapFrom(dest => $"{dest.Type.Name}Id"); } }
2. 注册全局约定
在项目启动配置AutoMapper时,注册这个自定义约定:
// .NET Core 6 中的Program.cs builder.Services.AddAutoMapper(cfg => { // 添加自定义前缀主键约定 cfg.AddMemberConfiguration().AddProvider(new PrefixIdConvention()); }, typeof(EntityToViewModelMappingProfile));
这样所有Profile中的映射都会自动遵循这个规则,无需在每个Profile中重复配置。
内容的提问来源于stack exchange,提问作者Ricardo Souza
相关产品推荐
相关产品推荐

