使用 Automapper 为成员创建地图

Creating maps for members using Automapper

我开始使用 AutoMapper 并有一个问题。我遇到了这样的示例代码:

Automapper.Mapper.CreateMap<Book, BookViewModel>()
    .ForMember(dest => dest.Author,
               opts => opts.MapFrom(src => src.Author.Name));

所以这会让我将一本书转换成一本书模型,然后将 src 映射到 src.author.name 属性 因为没有 1-1 映射。

确认一下,它不会自己反向工作,这意味着我现在需要明确地这样做:

Mapper.Mapper.CreateMap<BookViewModel, Book>()
    .ForMember(dest => dest.Author.Name,
               opts => opts.MapFrom(src => src.Author));

对吗?因此,为了进一步确认,如果我有 50 个视图模型和视图,我确实需要 100 个(一个用于入口,一个用于出口,加上 .ForMember 表达式中的任何其他代码行)

这是真的吗?这是一种常见的做法吗(即,您可能会看到数百行代码来处理属性与 1-1 不匹配的多个 DTO 来回的字段映射)?

CreateMap 为 AutoMapper 创建一个映射,以便稍后在需要时使用。这在您的应用程序的生命周期中只需要一次。为了使用你定义的这个映射,你只需要调用 Automapper.Map 方法。因此您不必一次又一次地创建映射。

示例:

var myBookViewModel = Automapper.Map<Book, BookViewModel>(myBook);

您说得对,定义 Book 到 BookViewModel 的映射器不会使 Automapper 自动为您创建 BookViewModel 到 Book 的映射器。您必须创建映射器。

本质上,您基本上需要指定来回配置来处理每个 DTO 映射。如果没有确定性模式,就不可能猜测当成员名称不同时复杂对象之间的映射如何工作,或者当您想要的属性在其他对象中更远时,就像在您的示例中一样。

但是,如果您遵循一些基本模式,Automapper 会相当聪明。在您的情况下,如果您将 DTO 属性 名称更改为 AuthorName 而不是 AuthorCreateMap 将正确映射而无需手动指定映射(他们称此 "Flattening"). Automapper 将 even map methods to properties if they follow a GetProperty() => Property { get; set; } pattern. Renaming your DTO properties to follow this pattern could probably save you a bunch of lines. Take a look at their starters guide 以其他方式简化您的映射。