找回密码
 立即注册
首页 业界区 业界 在 .NET 9 中使用 Mapster 快速、高效的实现对象映射 ...

在 .NET 9 中使用 Mapster 快速、高效的实现对象映射

蒲善思 8 小时前
1.png

前言

在日常开发中,我们常常需要将一个对象映射到另一个对象,比如将数据库实体转换为数据传输对象(DTO),或将请求模型映射为领域模型。这个过程通常涉及大量重复性代码,如果每次都手动编写,不仅严重影响开发效率,而且随着项目规模不断增长,还容易出现错误(如:属性遗漏、手写时写错或复制粘贴失误等)。
本文我们的主要内容就是讲解如何在 ASP.NET Core 9.0 Web API 项目中使用 Mapster 快速、高效的实现对象映射。
Mapster 介绍

Mapster 是一个开源免费(MIT license)、快速、高性能、灵活且易于使用的 .NET 对象映射库,用于在 .NET 用程序中进行对象之间的转换和映射操作,大幅减少手动赋值带来的重复代码、人为错误和维护成本。

  • 开源地址:https://github.com/MapsterMapper/Mapster
  • 在线文档:https://github.com/MapsterMapper/Mapster/wiki
2.png

安装 Mapster 相关包

方式一、NuGet 包管理器安装

在 NuGet 包管理器中搜索:Mapster 和 Mapster.DependencyInjection 安装:
Mapster 核心功能包
3.png

Mapster.DependencyInjection 依赖注入集成包
4.png

方式二、.NET CLI 安装
  1. dotnet add package Mapster --version 7.4.0 #核心功能包
  2. dotnet add package Mapster.DependencyInjection --version 1.0.1 #依赖注入集成包
复制代码
在 Program.cs 中注册 Mapster 服务
  1. var builder = WebApplication.CreateBuilder(args);

  2. // 注册 Mapster 服务
  3. builder.Services.AddMapster();

  4. // 注册 Mapster 映射规则
  5. MapsterConfig.Register();
复制代码
基础映射一行代码搞定

接下来我们分别定义一个源对象(Student)和一个目标对象(StudentViewModel),它们的属性名和类型完全一致。
Student(源对象)
  1.     public classStudent
  2.     {
  3.         /// <summary>
  4.         /// 学生ID [主键,自动递增]
  5.         /// </summary>
  6.         [PrimaryKey, AutoIncrement]
  7.         [Display(Name = "学生ID")]
  8.         publicint StudentID { get; set; }

  9.         /// <summary>
  10.         /// 班级ID
  11.         /// </summary>
  12.         [Display(Name = "班级ID")]
  13.         publicint ClassID { get; set; }

  14.         /// <summary>
  15.         /// 学生姓名
  16.         /// </summary>
  17.         [Display(Name = "学生姓名")]
  18.         publicstring Name { get; set; }

  19.         /// <summary>
  20.         /// 学生年龄
  21.         /// </summary>
  22.         [Display(Name = "学生年龄")]
  23.         publicint Age { get; set; }

  24.         /// <summary>
  25.         /// 学生性别
  26.         /// </summary>
  27.         [Display(Name = "学生性别")]
  28.         publicstring Gender { get; set; }
  29.     }
复制代码
StudentViewModel(目标对象)
  1.     public classStudentViewModel
  2.     {
  3.         /// <summary>
  4.         /// 学生ID
  5.         /// </summary>
  6.         [PrimaryKey, AutoIncrement]
  7.         [Display(Name = "学生ID")]
  8.         publicint StudentID { get; set; }

  9.         /// <summary>
  10.         /// 班级ID
  11.         /// </summary>
  12.         [Display(Name = "班级ID")]
  13.         publicint ClassID { get; set; }

  14.         /// <summary>
  15.         /// 学生姓名
  16.         /// </summary>
  17.         [Display(Name = "学生姓名")]
  18.         publicstring Name { get; set; }

  19.         /// <summary>
  20.         /// 学生年龄
  21.         /// </summary>
  22.         [Display(Name = "学生年龄")]
  23.         publicint Age { get; set; }

  24.         /// <summary>
  25.         /// 学生性别
  26.         /// </summary>
  27.         [Display(Name = "学生性别")]
  28.         publicstring Gender { get; set; }

  29.         /// <summary>
  30.         /// 班级名称
  31.         /// </summary>
  32.         [Display(Name = "班级名称")]
  33.         publicstring ClassName { get; set; }
  34.     }
复制代码
Mapster 自动完成映射

只要属性名和类型一致,Mapster 自动完成映射,无需任何配置!
  1.         private async Task<List<StudentViewModel>?> GetStudentClassInfo(List<Student> students)
  2.         {
  3.             // Mapster 映射(无需任何配置!)
  4.             var studentsListDto = students.Adapt<List<StudentViewModel>>();
  5.             if (studentsListDto?.Count > 0)
  6.             {
  7.                 var classIDs = studentsListDto.Select(x => x.ClassID).Distinct().ToList();
  8.                 var querySchoolClassList = await _schoolClassHelper.QueryAsync(x => classIDs.Contains(x.ClassID)).ConfigureAwait(false);
  9.                 if (querySchoolClassList?.Count > 0)
  10.                 {
  11.                     foreach (var studentItem in studentsListDto)
  12.                     {
  13.                         var getClassInfo = querySchoolClassList.FirstOrDefault(x => x.ClassID == studentItem.ClassID);
  14.                         if (getClassInfo != null)
  15.                         {
  16.                             studentItem.ClassName = getClassInfo.ClassName;
  17.                         }
  18.                     }
  19.                 }
  20.             }
  21.             return studentsListDto;
  22.         }
复制代码
映射结果输出:
5.png

自定义映射规则

当属性名或类型不一致时,可通过配置指定映射逻辑。
UserInfo(源对象)
  1.     public classUserInfo
  2.     {
  3.         publicint Id { get; set; }

  4.         publicstring FirstName { get; set; }

  5.         publicstring LastName { get; set; }

  6.         publicstring Email { get; set; }

  7.         public DateTime CreatedAt { get; set; }
  8.     }
复制代码
UserInfoViewModel(目标对象)
  1.     public classUserInfoViewModel
  2.     {
  3.         publicint Id { get; set; }

  4.         /// <summary>
  5.         /// 合并 FirstName + LastName
  6.         /// </summary>
  7.         publicstring FullName { get; set; }

  8.         publicstring Email { get; set; }

  9.         /// <summary>
  10.         /// 格式化日期
  11.         /// </summary>
  12.         publicstring CreatedDate { get; set; }
  13.     }
复制代码
配置 Mapster 映射规则

在项目根目录创建 MapsterConfig.cs:
  1.     /// <summary>
  2.     /// Mapster 全局映射配置类。
  3.     /// 用于集中注册项目中所有自定义的对象映射规则,
  4.     /// 避免映射逻辑分散在各处,提升可维护性与可测试性。
  5.     /// </summary>
  6.     publicstaticclassMapsterConfig
  7.     {
  8.         /// <summary>
  9.         /// 注册所有自定义的 Mapster 映射配置
  10.         /// 此方法应在应用程序启动时(如 Program.cs)调用一次
  11.         /// </summary>
  12.         public static void Register()
  13.         {
  14.             TypeAdapterConfig<UserInfo, UserInfoViewModel>
  15.                 .NewConfig()
  16.                 .Map(dest => dest.FullName,
  17.                      src => $"{src.FirstName} {src.LastName}".Trim())
  18.                 .Map(dest => dest.CreatedDate,
  19.                      src => src.CreatedAt.ToString("yyyy-MM-dd"));
  20.         }
  21.     }
复制代码
自定义映射规则
  1.     /// <summary>
  2.     /// 使用 Mapster 映射 UserInfo 示例
  3.     /// </summary>
  4.     [ApiController]
  5.     [Route("api/[controller]/[action]")]
  6.     publicclassUserInfoController : ControllerBase
  7.     {
  8.         privatereadonly IMapper _mapper;

  9.         /// <summary>
  10.         /// 依赖注入
  11.         /// </summary>
  12.         /// <param name="mapper">mapper</param>
  13.         public UserInfoController(IMapper mapper)
  14.         {
  15.             _mapper = mapper;
  16.         }

  17.         /// <summary>
  18.         /// GetUserInfo
  19.         /// </summary>
  20.         /// <returns></returns>
  21.         [HttpGet]
  22.         public List<UserInfoViewModel> GetUserInfos()
  23.         {
  24.             var userInfos = new List<UserInfo>
  25.             {
  26.                 new UserInfo
  27.                 {
  28.                     Id = 999,
  29.                     FirstName = "李",
  30.                     LastName = "四",
  31.                     Email = "lisi@qq.com",
  32.                     CreatedAt = DateTime.Now.AddYears(-5)
  33.                 },
  34.                 new UserInfo
  35.                 {
  36.                     Id = 666,
  37.                     FirstName = "张",
  38.                     LastName = "三",
  39.                     Email = "zhangsan@example.com",
  40.                     CreatedAt = DateTime.UtcNow.AddDays(-10)
  41.                 }
  42.             };

  43.             // 使用 Mapster 映射
  44.             var getUserInfoViewModels = _mapper.Map<List<UserInfoViewModel>>(userInfos);
  45.             return getUserInfoViewModels;
  46.         }
  47.     }
复制代码
映射结果输出:
6.png

完整示例源代码


  • https://github.com/YSGStudyHards/EasySQLite
7.png


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册