Automapper映射DTO到抽象类时的多集合合并映射问题
Automapper映射DTO到抽象类时的多集合合并映射问题
看起来你遇到了两个核心问题:一是要把DTO里的两个独立集合(Carriers和Cartridges)合并成目标类里的单个MugItems集合,二是AutoMapper不知道该如何处理抽象类MugItem的实例化——毕竟抽象类本身不能直接创建对象,得明确告诉它要映射成对应的具体子类(Carrier或Cartridge)。我来给你一步步解决这个问题:
第一步:先配置子类的映射关系
首先得让AutoMapper知道怎么把CarrierDTO转成Carrier,把CartridgeDTO转成Cartridge。这一步很关键,因为只有这样,AutoMapper才明白该如何把DTO子类转换成对应的领域子类(而不是试图去实例化抽象的MugItem)。
添加这两个映射配置:
// 配置CarrierDTO到Carrier的映射 CreateMap<CarrierDTO, Carrier>(); // 配置CartridgeDTO到Cartridge的映射 CreateMap<CartridgeDTO, Cartridge>();
如果这些子类的属性都是同名的,AutoMapper会自动完成属性映射,不需要额外配置。
第二步:合并集合并完成主映射
接下来修改MugDTO到Mug的映射,用自定义的逻辑把两个DTO集合合并成一个MugItems集合。这里有两种写法,选你觉得清晰的就行:
写法一:用MapFrom结合LINQ合并
CreateMap<MugDTO, Mug>() .ForMember(dest => dest.MugItems, opt => opt.MapFrom((src, _, context) => // 先把Carriers转成Carrier列表,再把Cartridges转成Cartridge列表,最后合并并转成MugItem集合 context.Mapper.Map<List<Carrier>>(src.Carriers) .Concat(context.Mapper.Map<List<Cartridge>>(src.Cartridges)) .Cast<MugItem>() .ToList() ));
写法二:用ResolveUsing写更直观的解析逻辑
如果你觉得LINQ的写法不够直观,也可以用ResolveUsing来写一个更清晰的解析器:
CreateMap<MugDTO, Mug>() .ForMember(dest => dest.MugItems, opt => opt.ResolveUsing((src, dest, _, context) => { var combinedItems = new List<MugItem>(); // 把Carriers转成Carrier并加入集合 combinedItems.AddRange(context.Mapper.Map<List<Carrier>>(src.Carriers)); // 把Cartridges转成Cartridge并加入集合 combinedItems.AddRange(context.Mapper.Map<List<Cartridge>>(src.Cartridges)); return combinedItems; }));
为什么你之前的写法会报错?
你之前只写了.ForMember(x => x.MugItems, m => m.MapFrom(s => s.Carriers)),有两个问题:
- 只处理了
Carriers集合,完全没合并Cartridges; - AutoMapper不知道该把
CarrierDTO转换成什么——你要求它转成MugItem,但MugItem是抽象类无法实例化,又没有提前配置CarrierDTO到具体子类的映射,所以就抛出了那个“无法创建抽象类实例”的错误。
备注:内容来源于stack exchange,提问作者Fred
相关产品推荐
相关产品推荐

