如何防止 AutoMapper 覆盖目标对象上的现有值?
Posted
技术标签:
【中文标题】如何防止 AutoMapper 覆盖目标对象上的现有值?【英文标题】:How to prevent AutoMapper from overwriting existing values on destination object? 【发布时间】:2021-12-05 12:28:59 【问题描述】:我有以下实体和对应的视图模型
public class TopEntity
public int Id get; set;
public ICollection<BottomEntity> Bottoms get; set;
public class BottomEntity
public int Id get; set;
public int TopId get; set;
public class TopEntityViewModel
public int Id get; set;
public ICollection<BottomEntityViewModel> Bottoms get; set;
public class BottomEntityViewModel
public int Id get; set;
我想将TopEntityViewModel
类型的实例映射到TopEntity
类型的实例,而不覆盖BottomEntity.TopId
上可能已经存在的任何值。
我已将 AutoMapper 配置如下:
var mapperConfig = new MapperConfiguration(exp =>
exp.CreateMap<TopEntity, TopEntityViewModel>();
exp.CreateMap<BottomEntity, BottomEntityViewModel>();
exp.CreateMap<TopEntityViewModel, TopEntity>();
exp.CreateMap<BottomEntityViewModel, BottomEntity>()
.ForMember(dest => dest.TopId, opts => opts.Ignore());
);
我在映射过程中添加了.ForMember(dest => dest.TopId, opts => opts.Ignore());
以忽略BottomEntity.TopId
,认为它应该有助于保留现有值。
我正在像这样映射实例:
mapperConfig.AssertConfigurationIsValid();
var mapper = mapperConfig.CreateMapper();
var topEntity = new TopEntity
Id = 45,
Bottoms = new List<BottomEntity>
new BottomEntity
Id = 56,
TopId = 45
,
new BottomEntity
Id = 57,
TopId = 45
;
var topEntityVm = new TopEntityViewModel
Id = 45,
Bottoms = new List<BottomEntityViewModel>
new BottomEntityViewModel
Id = 56,
,
new BottomEntityViewModel
Id = 57
;
var updatedTopEntity = mapper.Map(topEntityVm, topEntity);
当我访问 updatedTopEntity.Bottoms[<whatever>].TopId
时,它总是设置为 0。
如果我在类上更新我对属性BottomEntity.TopId
的定义以具有像1000
这样的默认值,则在映射后我的所有updatedTopEntity.Bottoms[<whatever>].TopId
都设置为该默认值(示例中为1000
)。
我检查了从 mapper.Map
返回的引用是否映射了原始引用并且它们确实如此。
如何防止 AutoMapper 删除现有实例上的任何现有值?
我正在使用 AutoMapper 10.1.1 和 .NET Core 5。You can try a working example here。
【问题讨论】:
你是否也检查过Bottoms
是否是同一个集合实例?
研究 AutoMapper.Collection.
【参考方案1】:
AutoMapper
说这个in the documentation:
映射到现有集合时,首先清除目标集合。如果这不是您想要的,请查看 AutoMapper.Collection。
AutoMapper.Collection,根据文档,这样做:
添加将集合映射到现有集合的功能,而无需重新创建集合对象。 将根据用户定义的源集合和目标集合中集合的通用项类型之间的等效性,从预先存在的集合对象中添加/更新/删除项。
安装AutoMapper.Collection
后我更新了AutoMapper配置如下:
var mapperConfig = new MapperConfiguration(exp =>
exp.AddCollectionMappers();
exp.CreateMap<TopEntity, TopEntityViewModel>();
exp.CreateMap<BottomEntity, BottomEntityViewModel>();
exp.CreateMap<TopEntityViewModel, TopEntity>();
exp.CreateMap<BottomEntityViewModel, BottomEntity>()
.ForMember(dest => dest.TopId, opts => opts.Ignore())
.EqualityComparison((src, dest) => src.Id == dest.Id);
);
.EqualityComparison((src, dest) => src.Id == dest.Id);
行添加了 AutoMapper 将使用的相等比较,如下所示:
AutoMapper.Collection
is described here的这种行为
工作示例:https://dotnetfiddle.net/tnaUjY
感谢Lucian Bargaoanu为我指出正确的方向
【讨论】:
以上是关于如何防止 AutoMapper 覆盖目标对象上的现有值?的主要内容,如果未能解决你的问题,请参考以下文章