用于封装的 AutoMapper 和嵌套对象映射

Posted

技术标签:

【中文标题】用于封装的 AutoMapper 和嵌套对象映射【英文标题】:AutoMapper and nested object mappings for encapsulation 【发布时间】:2019-04-13 05:31:36 【问题描述】:

我对 automapper 不太熟悉,但我们的软件架构师为这个项目向我介绍了它。

这个概念是对波动性的完全封装。这是一个制作不佳的图表

API/表示层 | 请求和响应后缀的对象。 (即ApplicationCreateRequest)


业务层 | 域传输对象的主页,后缀为 DTO。 (即ApplicationCreateDTO)


数据库层 | 后缀为RAO和Entity(即ApplicationEntity、ApplicationCreateRAO)的资源访问对象和实体的首页

我需要将 ApplicationCreateRequests 转换为 ApplicationCreateDTO,并将 Requests 嵌套对象也转换为 DTO。

例如:

public class ApplicationCreateRequest

    public string FirstName  get; set; 
    public string LastName  get; set; 

    public ContactCreateRequest Contact  get; set; 
    public DemographicCreateRequest Demographic  get; set; 
    public EducationCreateRequest Education  get; set; 
    public WorkCreateRequest Work  get; set; 

变成

public class ApplicationCreateDTO

    public string FirstName  get; set; 
    public string LastName  get; set; 

    public ContactCreateDTO Contact  get; set; 
    public DemographicCreateDTO Demographic  get; set; 
    public EducationCreateDTO Education  get; set; 
    public WorkCreateDTO Work  get; set; 

DTO 和请求在大多数情况下具有相同的属性。

我只开始使用非常基本的映射,例如:

CreateMap<ObjectOne, ObjectTwo>(); 

【问题讨论】:

【参考方案1】:

映射复杂模型的一种简单方法是声明,并将它们从最简单的(使用原生类型,例如:字符串、int 等)映射到复杂模型。

因此,您应该使用 CreateMap(以及其他最简单的方法)为 ContactCreateRequest 创建到 ContactCreateDTO 的简单映射。然后你将不得不创建类似的东西:

MapFrom 允许您指定要映射的属性(如果名称不同,则说明原因)。它还允许您从预定义的映射中指定结果,您只需告诉它您想要映射的成员...

Mapper.CreateMap<ApplicationCreateRequest, ApplicationCreateDTO>()
    .ForMember(g => g.FirstName, opt => opt.MapFrom(src => src.FirstName));
    .ForMember(g => g.LastName, opt => opt.MapFrom(src => src.LastName));
    .ForMember(g => g.Contact, opt => opt.MapFrom(src => Mapper.Map<ContactCreateRequest,ContactCreateDTO>(g.Contact)));
    .ForMember(g => g.Demographic, opt => opt.MapFrom(src => Mapper.Map<DemographicCreateRequest,DemographicCreateDTO>(g.Demographic)));
    .ForMember(g => g.Education, opt => opt.MapFrom(src => Mapper.Map<EducationCreateRequest,EducationCreateDTO>(g.Education)));
    .ForMember(g => g.Work, opt => opt.MapFrom(src => Mapper.Map<WorkCreateRequest,WorkCreateDTO>(g.Work)));

你可以使用

.ForMember(g => g.Property, opt => opt.Ignore()); // 忽略属性的映射

注意,在复杂的之前定义基本映射,否则你会遇到麻烦!

【讨论】:

以上是关于用于封装的 AutoMapper 和嵌套对象映射的主要内容,如果未能解决你的问题,请参考以下文章

Automapper 链/嵌套对象映射抛出异常

C# automapper 嵌套对象条件映射

AutoMapper 静态类不映射列表和嵌套实体

如何使用 AutoMapper 使用 EntityFramework 使用嵌套列表更新对象?

0.AutoMapper

AutoMapper,反向映射不适用于嵌入式对象?