7

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

 1 year ago
source link: https://blog.walterlv.com/post/convert-models-using-auto-mapper
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
吕毅 发表于 1 天前

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

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


关于 AutoMapper 的系列文章:

安装 AutoMapper 库

这是 AutoMapper 的官方 GitHub 仓库:

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

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

// 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 的映射器,用于后续映射使用
  2. 我们初始化了一个 Walterlv1Dao 类的实例
  3. 我们调用 mapper.Map 将其映射到 Walterlv1Vo 类型

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

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.”

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

复杂类型和集合

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

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 能处理这样的属性嵌套情况,只需要设置嵌套类型也能映射即可:

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

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

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

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

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; }
}

参考资料

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/convert-models-using-auto-mapper ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected])


Recommend

  • 71

    AutoMapper+ An automapper for PHP inspired by .NET's automapper. Transfers data from one object to another, allowing custom mapping operations. Table of Conten...

  • 49
    • www.tuicool.com 5 years ago
    • Cache

    AutoMapper&#39;s Design Philosophy

    While a lot of people use AutoMapper, and love it, I meet just as many people that hate it. When I hear their stories, it becomes clear to me that it's not that AutoMapper was "abused" per se, but that it was...

  • 64

    一、定义源映射对象 为了体现AutoMapper映射特性,在SocialAttribute中的Name属性没有定义在People中,People的Ear属性也不存在与SocialAttribute和PhysicalAttribute中。

  • 19
    • www.cnblogs.com 3 years ago
    • Cache

    Asp.NetCore之AutoMapper基础篇

    应用场景 现在由于前后端技术的分离,后端程序员在使用ORM框架开发后台API接口的时候,往往会将数据库的“数据模型”直接提供给前端。而大多数时候,可能这些数据并不能够满足前端展示的需求,有时候可能需要在“...

  • 9

    Separation between Data Transfer Objects and Entities, and Automapper to the rescue One question we had a little while ago. When you return objects from a controller, should they be the same objects you get out of your da...

  • 11
    • 微信 mp.weixin.qq.com 3 years ago
    • Cache

    对象到对象映射-AutoMapper

    概述 AutoMapper 是一个对象-对象映射器,可以将一个对象映射到另一个对象。 用来解决一个看似复杂的问题,这种类型的代码编写起来相当枯燥乏味, 官网地址: http://automapper.org/

  • 10
    • jimmybogard.com 3 years ago
    • Cache

    AutoMapper LINQ Support Deep Dive

    AutoMapper AutoMapper LINQ Support Deep Dive Jimmy Bogard...

  • 12
    • jimmybogard.com 3 years ago
    • Cache

    AutoMapper 9.0 Released

    AutoMapper AutoMapper 9.0 Released

  • 2
    • cezarypiatek.github.io 2 years ago
    • Cache

    我不使用 AutoMapper 的原因。

  • 2

    吕毅 发表于 1 天前 使用 AutoMapper 可以很方便地在不同的模型之间进行转换而减少编写太多的转换代码。不过,如果各个模型之间存在一些差异的话(比如多出或缺少一些属性),简单的配置便不太行。本文帮助你解决...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK