如何用AutoMapper更新已有Dest实例,合并SourceA与SourceB的值?
问题描述
我定义了以下类:
public class SourceA { public double SourceAProp { get; set; } } public class SourceB { public double SourceBProp { get; set; } } public class Dest { public double SourceAProp { get; set; } public double SourceBProp { get; set; } }
我尝试了如下代码:
var config = new MapperConfiguration(cfg => cfg.CreateMap<SourceA, Dest>()); var mapper = config.CreateMapper(); var dest = mapper.Map<SourceA, Dest>(sourceA.Value); config = new MapperConfiguration(cfg => cfg.CreateMap<SourceB, Dest>()); mapper = config.CreateMapper(); dest = mapper.Map<SourceB, Dest>(sourceB.Value);
但我发现每次执行Map方法都会创建新的实例。请问如何使用AutoMapper创建一个包含SourceA和SourceB实例值的单一Dest实例(或在首次执行后更新已创建的实例)?
解决方案
其实很简单,AutoMapper本身就支持更新已有的对象,你之前的问题主要是两个点:一是每次都重新创建了Mapper配置和实例,二是没有利用Map方法的重载来更新已存在的Dest对象。
给你两种可行的实现方式,都能达到你要的效果:
方式一:先创建Dest实例,再逐步更新
首先我们一次性把所有需要的映射都配置好,不用反复创建配置和Mapper,然后先通过SourceA生成Dest实例,再用SourceB的属性去更新这个实例:
// 一次性配置好两个映射,复用同一个配置和Mapper var config = new MapperConfiguration(cfg => { cfg.CreateMap<SourceA, Dest>(); cfg.CreateMap<SourceB, Dest>(); }); var mapper = config.CreateMapper(); // 第一步:用SourceA创建初始的Dest实例 var dest = mapper.Map<SourceA, Dest>(sourceA.Value); // 第二步:把SourceB的属性更新到已有的dest对象里,不会新建实例 mapper.Map(sourceB.Value, dest);
方式二:手动初始化空Dest,再依次映射
如果你不想从SourceA生成初始实例,也可以手动new一个空的Dest,然后分别把SourceA和SourceB的属性映射进去:
var config = new MapperConfiguration(cfg => { cfg.CreateMap<SourceA, Dest>(); cfg.CreateMap<SourceB, Dest>(); }); var mapper = config.CreateMapper(); // 手动创建空的Dest实例 var dest = new Dest(); // 依次映射两个源对象到同一个Dest实例 mapper.Map(sourceA.Value, dest); mapper.Map(sourceB.Value, dest);
关键注意点:
- 别反复创建
MapperConfiguration和Mapper:AutoMapper的配置是重量级的,一次性配好所有映射复用即可,反复创建只会浪费性能。 - 用对Map的重载:
mapper.Map(source, existingDest)这个重载是专门用来更新已有对象的,它会直接修改你传入的existingDest,返回值也是同一个对象。 - 你的类结构刚好符合AutoMapper的默认规则:同名属性会自动匹配,所以不需要额外写映射规则,直接用就好。
内容的提问来源于stack exchange,提问作者ohadinho
相关产品推荐
相关产品推荐

