Automapper:使用ReverseMap()和ForMember()实现双向映射

76

我有一个情况,需要将实体映射到视图模型并进行反向映射。我必须使用 ForMember() 明确指定映射,因为它们的属性名称不完全相同。这里是一个简短的示例,展示我的类是如何看起来的:

public class PartTwo {
    public int Integer { get; set; }
}

public class PartTwoViewModel {
    public int PartInteger { get; set; }
}

我希望以这种方式使用它们:

Mapper.CreateMap<PartTwo, PartTwoViewModel>()
    .ForMember(dst => dst.PartInteger, opt => opt.MapFrom(src => src.Integer))
    .ReverseMap();

var partTwoViewModel = new PartTwoViewModel() { PartInteger = 42 };
var partTwo = Mapper.Map<PartTwoViewModel, PartTwo>(partTwoViewModel);
Assert.AreEqual(partTwoViewModel.PartInteger, partTwo.Integer);

但是它无法将属性PartInteger匹配为Integer。(Integer0。)

有没有办法让这个工作?(当两个类的属性名称相同时,它可以工作。)我是否需要在方法ForMember()中设置某种选项?


我刚刚尝试了你的ReverseMap方法,它很好用。这个问题已经过时了。 - Boiethios
2个回答

166

ReverseMap 返回一个代表反向映射的 IMappingExpression。一旦调用此方法,随后的调用将用于配置该映射的反向。

这里是一个示例:

Mapper.CreateMap<CartItemDto, CartItemModel>()
      .ForMember(dest => dest.ExtendedCost, opt => opt.Ignore())
      .ReverseMap()
          .ForMember(dest => dest.Pricing, opt => opt.Ignore())

这将在反向方向上忽略Pricing字段。


1
很好。虽然重新创建成员映射仍然有些不方便,但这比创建全新的映射要好得多。 - Cody
@jon Wingfield,感谢您的回答,但我还有点困惑。如果我在调用ReverseMap之后仍然需要重新执行所有的.ForMember调用,那么这对我有什么好处呢?是.ignore出了问题吗? - JMarsch
1
@JMarsch 好久不见了,但我认为你不需要重新做所有的 ForMember 调用,只需处理那些尚未映射的调用即可。 - Jon Wingfield

56

您可以像这样定义您的配置:

Mapper.CreateMap<PartTwo, PartTwoViewModel>()
    .ForMember(dst => dst.PartInteger, opt => opt.MapFrom(src => src.Integer));

Mapper.CreateMap<PartTwoViewModel, PartTwo>()
    .ForMember(dst => dst.Integer, opt => opt.MapFrom(src => src.PartInteger));

更新

这是 提交记录,其中最初实现了ReverseMap。从我在代码中看到的内容来看,它只创建一个简单的反向映射。例如,在此情况下,它会自动配置相当于:

Mapper.CreateMap<PartTwoViewModel, PartTwo>();

要得到更复杂的东西,恐怕你必须手动进行配置。


1
是的,这个可以工作。我希望不必定义反向映射,因为我有很多属性是通过ForMember()进行映射的。 - toni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接