如何配置AutoMapper实现继承层级下ICollection<T>属性的自动映射
AutoMapper ICollection类型继承映射优化方案
你之前配置失效的核心原因:实体类中使用new关键字隐藏了父类的Items属性,本质上子类的Items和父类的Items是两个完全独立的成员,AutoMapper默认的继承映射规则不会自动关联这两个属性,因此需要显式指定映射规则。
可实现一行映射的AutoMapper配置方案
无需额外写Linq处理集合,只需在原有继承映射的基础上,为每个Foo子类的Items属性指定映射关系即可:
// 配置Bar继承链的映射关系 Mapper.CreateMap<Baz, Bar>() .Include<Zoo, Baz>(); Mapper.CreateMap<Zoo, Baz>(); // 配置Foo继承链的映射,显式绑定隐藏的Items属性 Mapper.CreateMap<Foobar, Foo>() .ForMember(dest => dest.Items, opt => opt.MapFrom(src => src.Items)); Mapper.CreateMap<Foobarbaz, Foo>() .ForMember(dest => dest.Items, opt => opt.MapFrom(src => src.Items));
配置完成后直接调用Mapper.Map<Foo>(foobarbaz);即可完成全部映射,包含ICollection集合的自动类型转换。
其他优化建议
- 若你使用的是AutoMapper 9.0及以上版本,静态
Mapper.CreateMap方法已被弃用,建议改用Profile方式配置映射,配合依赖注入使用,代码更易维护:
// 自定义映射配置类 public class MyMappingProfile : Profile { public MyMappingProfile() { // Bar继承链映射 CreateMap<Baz, Bar>().Include<Zoo, Baz>(); CreateMap<Zoo, Baz>(); // Foo继承链映射 CreateMap<Foobar, Foo>() .ForMember(dest => dest.Items, opt => opt.MapFrom(src => src.Items)); CreateMap<Foobarbaz, Foo>() .ForMember(dest => dest.Items, opt => opt.MapFrom(src => src.Items)); } } // ASP.NET Core 服务注册示例 builder.Services.AddAutoMapper(typeof(MyMappingProfile)); // 业务代码中注入IMapper后使用 var result = _mapper.Map<Foo>(foobarbazInstance);
- 若后续需要扩展更多Foo的子类,可通过反射批量扫描所有继承自Foo的子类,自动添加
Items属性的映射规则,无需重复手动配置。 - 你提到的通过重写Bar类方法实现映射的方案也是可行的,该方案不需要引入AutoMapper依赖,运行性能更高,适合映射逻辑固定、对性能要求高的场景;如果项目中存在大量类似的映射需求,AutoMapper的配置方案维护成本更低。
内容的提问来源于stack exchange,提问作者Kamil Z
相关产品推荐
相关产品推荐

