使用 AutoMapper 自动在多个数据模型间进行转换

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 AutoMapper 自动在多个数据模型间进行转换相关的知识,希望对你有一定的参考价值。

访问数据库、IPC 通信、业务模型、视图模型……对于同一个业务的同一种数据,经常会使用多种数据模型工作在不同的代码模块中。这时它们之间的互相转换便是大量的重复代码了。

使用 AutoMapper 便可以很方便地在不同的模型之间进行转换而减少编写太多的转换代码(如果这一处的代码对性能不太敏感的话)。

关于 AutoMapper 的系列文章:

  • 使用 AutoMapper 自动在多个数据模型间进行转换

  • 使用 AutoMapper 自动映射模型时,处理不同模型属性缺失的问题

安装 AutoMapper 库

这是 AutoMapper 的官方 GitHub 仓库:

  • AutoMapper/AutoMapper: A convention-based object-object mapper in .NET.

安装 AutoMapper 的 NuGet 包即可在项目中使用 AutoMapper。

入门

以下是一个最简单的控制台演示程序的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Program.cs
var mapper = InitializeMapper();

var dao = new Walterlv1Dao

    Id = "2ed3558ac938438fb2c1d2de71d7bb90",
    Name = "walterlv",
    Text = "blog.walterlv.com",
;
var vo = mapper.Map<Walterlv1Vo>(dao);
Console.WriteLine($"Name = vo.Name, Text = vo.Text");

static IMapper InitializeMapper()

    var configuration = new MapperConfiguration(cfg =>
    
        cfg.CreateMap<Walterlv1Dao, Walterlv1Vo>();
    );
#if DEBUG
    configuration.AssertConfigurationIsValid();
#endif
    var mapper = configuration.CreateMapper();
    return mapper;

在这段代码中:

  1. 我们定义了一个方法 InitializeMapper,在里面初始化 IMapper 的新实例。

  • 初始化 MapperConfiguration,定义类型的映射关系

  • 在 DEBUG 下验证 MapperConfiguration 的映射是否正确

  • 创建一个 IMapper 的映射器,用于后续映射使用

我们初始化了一个 Walterlv1Dao 类的实例

我们调用 mapper.Map 将其映射到 Walterlv1Vo 类型

这两个类型的定义如下(虽然无关紧要)。

1
2
3
4
5
6
7
8
9
10
11
12
public class Walterlv1Dao

    public string? Id  get; set; 
    public string? Name  get; set; 
    public string? Text  get; set; 

public class Walterlv1Vo

    public string? Id  get; set; 
    public string? Name  get; set; 
    public string? Text  get; set; 

如果你的应用程序中会使用到依赖注入,那么只需要把拿到的 IMapper 加入即可。

如果希望两个类型之间能够双向映射,那么在初始化 IMapper 的时候也应该再额外调用一下 ReverseMap 方法,否则就会抛出异常 AutoMapper.AutoMapperMappingException:“Missing type map configuration or unsupported mapping.”。

1
cfg.CreateMap<Walterlv1Dao, Walterlv1Vo>().ReverseMap();

复杂类型和集合

现在,我们让模型稍复杂一些:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Walterlv1Dao

    public string? Id  get; set; 
    public string? Name  get; set; 
    public FriendDao? Friend  get; set; 

public class FriendDao

    public string? Id  get; set; 
    public string? Name  get; set; 

public class Walterlv1Vo

    public string? Id  get; set; 
    public string? Name  get; set; 
    public FriendVo? Friend  get; set; 

public class FriendVo

    public string? Id  get; set; 
    public string? Name  get; set; 

AutoMapper 能处理这样的属性嵌套情况,只需要设置嵌套类型也能映射即可:

1
2
cfg.CreateMap<Walterlv1Dao, Walterlv1Vo>().ReverseMap();
cfg.CreateMap<FriendDao, FriendVo>().ReverseMap();

如果两个模型中子模型的类型是一样的,那么只会进行简单的赋值,而不会创建新的对象。

例如上面例子里,如果 FriendDao 和 FriendVo 合并成 Friend 类型,两个类型都使用这个合并的类型,那么映射之后,Friend 将是同一个对象。

除了复杂类型,列表也是可以的:

1
2
3
4
5
6
7
8
9
10
11
12
public class Walterlv1Dao

    public string? Id  get; set; 
    public string? Name  get; set; 
    public List<FriendDao>? Friend  get; set; 

public class Walterlv1Vo

    public string? Id  get; set; 
    public string? Name  get; set; 
    public List<FriendVo>? Friend  get; set; 

参考资料

  • AutoMapper/AutoMapper: A convention-based object-object mapper in .NET.

以上是关于使用 AutoMapper 自动在多个数据模型间进行转换的主要内容,如果未能解决你的问题,请参考以下文章

如何使用automapper映射与多个表的数据集

AutoMapper完成Dto与Model的转换

使用AutoMapper实现Dto和Model的自由转换(上)

[使用Automapper时,我是否也应该展平/映射视图模型的内部objetc?

使用 AutoMapper 映射两个模型

OOM框架AutoMapper基本使用