You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让AutoMapper仅创建一次目标对象并复用它们

解决AutoMapper中重复生成目标对象的问题

你遇到的这个场景确实是AutoMapper的常见需求,它内置了现成的功能来保持源对象的引用关系,完全不需要手动维护对象存储字典。下面给你两种可行的解决方案:

方法一:为特定映射启用引用保留

AutoMapper提供了PreserveReferences()配置方法,它会自动跟踪已经映射过的源对象,当再次遇到同一个源引用时,直接复用之前生成的目标对象实例。

修改你的映射配置代码,在SourceAuthor到DestinationAuthor的映射上添加这个配置即可:

var mapper = new MapperConfiguration(
    cfg =>
    {
        cfg.CreateMap<SourceBlog, DestinationBlog>();
        cfg.CreateMap<SourceAuthor, DestinationAuthor>()
           .PreserveReferences(); // 新增这一行,开启引用保留
    }).CreateMapper();

修改完成后,你的Trace.Assert(destinationBlogs.Select(b => b.Author).Distinct().Count() == 2);断言就会顺利通过——因为两篇博客引用的John是同一个源对象,AutoMapper只会生成一个DestinationAuthor实例,然后被两篇博客复用。

方法二:全局启用引用保留(可选)

如果你希望项目中所有的映射都自动保留引用关系,可以直接在全局配置中开启:

var mapper = new MapperConfiguration(
    cfg =>
    {
        cfg.PreserveReferences(); // 全局开启引用保留
        cfg.CreateMap<SourceBlog, DestinationBlog>();
        cfg.CreateMap<SourceAuthor, DestinationAuthor>();
    }).CreateMapper();

不过这种方式会对所有映射类型生效,如果你只需要特定类型保持引用关系,方法一更灵活。

额外场景:按对象标识而非引用判断

如果你的源对象不是同一个内存引用,但逻辑上属于同一个实体(比如从数据库查询出的不同实例但ID相同),可以用EqualityComparison来指定自定义的判断规则:

cfg.CreateMap<SourceAuthor, DestinationAuthor>()
   .EqualityComparison((src, otherSrc) => src.AuthorId == otherSrc.AuthorId);

这样即使源对象是不同的实例,只要AuthorId相同,AutoMapper也会复用同一个目标实例。

内容的提问来源于stack exchange,提问作者lauxjpn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 06:07:31