4. 对象映射 - Mapping.Mapster

这篇具有很好参考价值的文章主要介绍了4. 对象映射 - Mapping.Mapster。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在项目中我们会经常遇到对象的映射,比如像Model和Dto之间的映射,或者是对象的深拷贝,这些都是需要我们自己实现的。此时,项目中会出现很多初始化对象的代码,这些代码写起来相当的枯燥乏味,那么有没有什么办法减轻我们的工作量,使得我们可以把时间花费到业务功能上呢?

目前,.Net中的对象映射框架,功能强大且性能极佳的对象映射框架已经存在,其中使用最多的有:

  • Mapster
  • AutoMapper

说到对象映射框架,大家想到的最多的是AutoMapper,可能很多人连Mapster都没听过,但不可否认的是Mapster确实是一个很好的对象映射框架,但由于中文文档的缺失,导致在国内知名度不是很高,今天我们就来介绍一下Mapster提供了哪些功能,如何在项目中使用它,Masa提供的Mapster又做了什么?

Mapster 简介

Mapster是一个使用简单,功能强大的对象映射框架,自2014年开源到现在已经过去8个年头,截止到现在,github上已经拥有2.6k的star,并保持着每年3次的发版频率,其功能与AutoMapper类似,提供对象到对象的映射、并支持IQueryable到对象的映射,与AutoMapper相比,在速度和内存占用方面表现的更加优秀,可以在只使用1/3内存的情况下获得4倍的性能提升,那我们下面就来看看Mapster如何使用?

准备工作

  • 新建一个控制台项目Assignment.Mapster,并安装Mapster

    dotnet add package Mapster --version 7.3.0
    

映射到新对象

  1. 新建类UserDto

    public class UserDto
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public uint Gender { get; set; }
    
        public DateTime BirthDay { get; set; }
    }
    
  2. 新建一个匿名对象,作为待转换的对象源

    var user = new
    {
        Id = 1,
        Name = "Tom",
        Gender = 1,
        BirthDay = DateTime.Parse("2002-01-01")
    };
    
  3. 将user源对象映射到为目标对象 (UserDto)

    var userDto = user.Adapt<UserDto>();
    Console.WriteLine($"映射到新对象,Name: {userDto.Name}");
    

运行控制台程序验证转换成功:
4. 对象映射 - Mapping.Mapster

数据类型

除了提供对象到对象的映射,还支持数据类型的转换,如:

基本类型
  • 提供类型映射的功能,类似Convert.ChangeType()

    string res = "123";
    decimal i = res.Adapt<decimal>(); //equal to (decimal)123;
    Console.WriteLine($"结果为:{i == int.Parse(res)}");
    

运行控制台程序: 4. 对象映射 - Mapping.Mapster

枚举类型
  • 把枚举映射到数字类型,同样也支持字符串到枚举和枚举到字符串的映射,比.NET的默认实现快两倍

    var fileMode = "Create, Open".Adapt<FileMode>();//等于 FileMode.Create | FileMode.Open
    Console.WriteLine($"枚举类型转换的结果为:{fileMode == (FileMode.Create | FileMode.Open)}");
    

运行控制台程序验证转换成功:
4. 对象映射 - Mapping.Mapster

Queryable扩展

Mapster提供了Queryable的扩展,用于实现DbContext的按需查找,例如:

  1. 新建类UserDbContext

    using Assignment.Mapster.Domain;
    using Microsoft.EntityFrameworkCore;
    
    namespace Assignment.Mapster.Infrastructure;
    
    public class UserDbContext : DbContext
    {
        public DbSet<User> User { get; set; }
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var dataBaseName = Guid.NewGuid().ToString();
            optionsBuilder.UseInMemoryDatabase(dataBaseName);//使用内存数据库,方便测试
        }
    }
    
  2. 新建类User

    public class User
    {
        public int Id { get; set; }
    
        public string Name { get; set; }
    
        public uint Gender { get; set; }
    
        public DateTime BirthDay { get; set; }
    
        public DateTime CreationTime { get; set; }
    
        public User()
        {
            CreationTime = DateTime.Now;
        }
    }
    
  3. 使用基于Queryable的扩展方法ProjectToType

    using (var dbContext = new UserDbContext())
    {
        dbContext.Database.EnsureCreated();
    
        dbContext.User.Add(new User()
        {
            Id = 1,
            Name = "Tom",
            Gender = 1,
            BirthDay = DateTime.Parse("2002-01-01")
        });
        dbContext.SaveChanges();
    
        var userItemList = dbContext.User.ProjectToType<UserDto>().ToList();
    }
    

运行控制台程序验证转换成功:
4. 对象映射 - Mapping.Mapster

除此之外,Mapster还提供了映射前/后处理,拷贝与合并以及映射配置嵌套支持,详细可查看文档,既然Mapster已经如此强大,那我直接使用它就可以了,为什么还要使用Masa提供的Mapper呢?

什么是Masa.Contrib.Data.Mapping.Mapster?

Masa.Contrib.Data.Mapping.Mapster是基于Mapster的一个对象到对象的映射器,并在原来Mapster的基础上增加自动获取并使用最佳构造函数映射,支持嵌套映射,减轻映射的工作量。

映射规则

  • 目标对象没有构造函数时:使用空构造函数,映射到字段和属性。

  • 目标对象存在多个构造函数:获取最佳构造函数映射

    最佳构造函数: 目标对象构造函数参数数量从大到小降序查找,参数名称一致(不区分大小写)且参数类型与源对象属性一致

准备工作

  • 新建一个控制台项目Assignment.Masa.Mapster,并安装Masa.Contrib.Data.Mapping.MapsterMicrosoft.Extensions.DependencyInjection

    dotnet add package Masa.Contrib.Data.Mapping.Mapster --version 0.4.0-rc.4
    dotnet add package Microsoft.Extensions.DependencyInjection --version 6.0.0
    
  1. 新建类OrderItem

    public class OrderItem
    {
        public string Name { get; set; }
    
        public decimal Price { get; set; }
    
        public int Number { get; set; }
    
        public OrderItem(string name, decimal price) : this(name, price, 1)
        {
    
        }
    
        public OrderItem(string name, decimal price, int number)
        {
            Name = name;
            Price = price;
            Number = number;
        }
    }
    
  2. 新建类Order

    public class Order
    {
        public string Name { get; set; }
    
        public decimal TotalPrice { get; set; }
    
        public List<OrderItem> OrderItems { get; set; }
    
        public Order(string name)
        {
            Name = name;
        }
    
        public Order(string name, OrderItem orderItem) : this(name)
        {
            OrderItems = new List<OrderItem> { orderItem };
            TotalPrice = OrderItems.Sum(item => item.Price * item.Number);
        }
    }
    
  3. 修改类Program

    using Assignment.Masa.Mapster.Domain.Aggregate;
    using Masa.BuildingBlocks.Data.Mapping;
    using Masa.Contrib.Data.Mapping.Mapster;
    using Microsoft.Extensions.DependencyInjection;
    
    Console.WriteLine("Hello Masa Mapster!");
    
    IServiceCollection services = new ServiceCollection();
    services.AddMapping();
    
    var request = new
    {
        Name = "Teach you to learn Dapr ……",
        OrderItem = new OrderItem("Teach you to learn Dapr hand by hand", 49.9m)
    };
    var serviceProvider = services.BuildServiceProvider();
    var mapper = serviceProvider.GetRequiredService<IMapper>();
    var order = mapper.Map<Order>(request);
    
    Console.WriteLine($"{nameof(Order.TotalPrice)} is {order.TotalPrice}");//控制台输出49.9
    
    Console.ReadKey();
    

如果转换成功,TotalPrice的值应该是49.9,那么我们运行控制台程序来验证转换是否成功:

4. 对象映射 - Mapping.Mapster

如何实现

上面我们提到了Masa.Contrib.Data.Mapping.Mapster可以自动获取并使用最佳构造函数映射,进而完成对象到对象的映射,那么它是如何实现的呢?会不会对性能有什么影响呢?

做到自动获取并使用最佳构造函数映射是使用的Mapster提供的构造函数映射的功能,通过指定构造函数,完成对象到对象的映射。

查看文档

总结

目前Masa.Contrib.Data.Mapping.Mapster的功能相对较弱,当前版本与Mapster的相比仅仅增加了一个自动获取并使用最佳构造函数的功能,让我们在面对无空构造函数且拥有多个构造函数的类时也能轻松的完成映射,不需要额外多写一行代码。

但我觉得Masa版的Mapping最大的好处是项目依赖的是BuildingBlocks下的IMapper,而不是Mapster,这也就使得我们的项目与具体的映射器实现脱离,如果我们被要求项目必须要使用AutoMapper,只需要实现AutoMapper版的IMapper即可,无需更改太多的业务代码,仅需要更换一下引用的包即可,这也是BuildingBlocks的魅力所在

本章源码

Assignment04

https://github.com/zhenlei520/MasaFramework.Practice

开源地址

MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks

MASA.Contrib:https://github.com/masastack/MASA.Contrib

MASA.Utils:https://github.com/masastack/MASA.Utils

MASA.EShop:https://github.com/masalabs/MASA.EShop

MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor

如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们文章来源地址https://www.toymoban.com/news/detail-442496.html

到了这里,关于4. 对象映射 - Mapping.Mapster的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Elasticsearch学习笔记二】es的Mapping字段映射、Mapping字段常用类型、Mapping映射的创建、查看和更新、es数据迁移、ik分词器

    目录 1、Mapping字段映射概述 2、Mapping字段常用类型 3、映射中对时间类型详解 1)采取自动映射器来映射 2)手工映射提前指定日期类型 4、ES的keyword的属性ignore_above 5、Mapping映射的查看和创建 1)查看mapping信息:GET 索引名/_mapping 2)创建映射:PUT /索引名 3) 查看所有索引映

    2024年01月20日
    浏览(47)
  • (4)Mapping(映射)

    映射是定义文档及其包含的字段的存储和索引方式的过程。 两种映射方式 dynamic mapping(动态映射或自动映射) expllcit mapping(静态映射或手工映射或显示映射) Mapping数据类型 Mapping参数 https://www.elastic.co/guide/en/elasticsearch/reference/7.10/removal-of-types.html Mapping 也称之为映射,定义

    2024年02月01日
    浏览(27)
  • Mapping映射入门

    概念:自动或手动为index中的_doc建立的一种数据结构和相关配置,简称为mapping映射。 插入几条数据,让es自动为我们建立一个索引 对比数据库建表语句 动态映射:dynamic mapping,自动为我们建立index,以及对应的mapping,mapping中包含了每个field对应的数据类型,以及如何分词等

    2023年04月08日
    浏览(26)
  • (4)elasticsearch的Mapping(映射)

    映射是定义文档及其包含的字段的存储和索引方式的过程。 两种映射方式 dynamic mapping(动态映射或自动映射) expllcit mapping(静态映射或手工映射或显示映射) Mapping数据类型 Mapping参数 https://www.elastic.co/guide/en/elasticsearch/reference/7.10/removal-of-types.html Mapping 也称之为映射,定义

    2024年02月03日
    浏览(24)
  • Elasticsearch学习-索引操作及Mapping映射

    在7.X版本前类似于关系型数据库中的数据库概念,8.X版本后删除了type概念,索引类似于关系型数据库中的表 相当于关系型数据库中的一条数据,最小单元 每一个节点就是一个ES实例(一个java进程),一个节点 != 一台服务器 多个节点组成分布式系统,ES原生分布式,已启动一

    2023年04月22日
    浏览(31)
  • 深入理解Elasticsearch的索引映射(mapping)

    当我们谈论Elasticsearch时,索引映射是一个核心概念,它定义了如何存储和检索数据。在Elasticsearch 7.6及更高版本中,映射提供了一系列强大的功能,使您能够精确地控制数据的结构和行为。本文将详细介绍映射的关键属性、用途以及如何正确设置和优化它。 在Elasticsearch中,

    2024年02月22日
    浏览(36)
  • elasticsearch中文档映射Mapping用法详解

    Mapping类似数据库中的schema的定义,作用如下: 定义索引中的字段的名称 定义字段的数据类型,例如字符串,数字,布尔等 字段,倒排索引的相关配置(Analyzed or Not Analyzed,Analyzer) ES中Mapping映射可以分为动态映射和静态映射。 动态映射:         在关系数据库中,需要事先创

    2024年02月16日
    浏览(33)
  • Elasticsearch:映射(mapping)的实用实践指南

    动态映射适用于开发环境,但对于生产级集群禁用它。 将动态配置为 “strict” 以对索引的字段值实施严格模式。有关动态映射的详细描述,请阅读文章 “Elasticsearch:Dynamic mapping”。 当文档大量存储时,可以在定义字段映射时使用优化来节省磁盘空间。 禁用强制(coerce)。

    2024年02月12日
    浏览(25)
  • Elasticsearch:Explicit mapping - 显式映射

    显式映射相比较动态映射(Dynamic mapping)是需要我们在索引创建时就定义字段及其类型。这个和我们传统的 RDMS 数据库一样,在我们写入数据到数据库之前,我们需要工整地定义好每个字段及其类型和长度。Elasticsearch 既可以使用显式映射也可以同时使用动态映射。在许多的

    2024年02月02日
    浏览(37)
  • es elasticsearch 八 mapping 映射 、复杂数据类型

    目录 Mapping 映射 复杂数据类型 Mapping 映射 精确匹配 必须和对应字段值安全一致才可查出 全文检索 缩写搜索全程、格式转换 大小写 同义词 全文检索核心原理 分词,初步的倒排索引的建立 重建倒排索引 时态转换、重复数的转换、同义词的转换、大小写的转换 分词器 analy

    2024年02月07日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包