伏波将军 發表於 2025-10-22 08:48:56

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

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">前言</a></li><li><a href="#_label1">Mapster 介绍</a></li><li><a href="#_label2">安装 Mapster 相关包</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_0">方式一、NuGet 包管理器安装</a></li><li><a href="#_lab2_2_1">方式二、.NET CLI 安装</a></li></ul><li><a href="#_label3">在 Program.cs 中注册 Mapster 服务</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">基础映射一行代码搞定</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_2">Student(源对象)&nbsp;&nbsp;&nbsp;&nbsp;</a></li><li><a href="#_lab2_4_3">StudentViewModel(目标对象)&nbsp;&nbsp;&nbsp;&nbsp;</a></li><li><a href="#_lab2_4_4">Mapster 自动完成映射</a></li></ul><li><a href="#_label5">自定义映射规则</a></li><ul class="second_class_ul"><li><a href="#_lab2_5_5">UserInfo(源对象)</a></li><li><a href="#_lab2_5_6">UserInfoViewModel(目标对象)&nbsp;&nbsp;&nbsp;&nbsp;</a></li><li><a href="#_lab2_5_7">配置 Mapster 映射规则</a></li><li><a href="#_lab2_5_8">自定义映射规则&nbsp;&nbsp;&nbsp;&nbsp;</a></li></ul><li><a href="#_label6">完整示例源代码</a></li><ul class="second_class_ul"></ul></ul></div><p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492263.png" /></p>
<p class="maodian"><a name="_label0"></a></p><h2>前言</h2>
<p><span>在日常开发中,我们常常需要将一个对象映射到另一个对象,比如将数据库实体转换为数据传输对象(DTO),或将请求模型映射为领域模型。这个过程通常涉及大量重复性代码,如果每次都手动编写,不仅严重影响开发效率,而且随着项目规模不断增长,还容易出现错误(如:属性遗漏、手写时写错或复制粘贴失误等)。</span></p>
<p><span>本文我们的主要内容就是讲解如何在&nbsp;</span><code>ASP.NET Core 9.0 Web API</code><span><span>&nbsp;项目中使用 Mapster 快速、高效的实现对象映射。</span></span></p>
<p class="maodian"><a name="_label1"></a></p><h2>Mapster 介绍</h2>
<p><span>Mapster 是一个开源免费(<span>MIT license)、快速、高性能、灵活且易于使用的 .NET 对象映射库,用于在 .NET 用程序中进行对象之间的转换和映射操作,大幅减少手动赋值带来的重复代码、人为错误和维护成本。</span></span></p>
<ul><li>开源地址:<span><a href="https://github.com/MapsterMapper/Mapster" rel="external nofollow" target="_blank">https://github.com/MapsterMapper/Mapster</a></span></li><li>在线文档:<span><a href="https://github.com/MapsterMapper/Mapster/wiki" rel="external nofollow" target="_blank">https://github.com/MapsterMapper/Mapster/wiki</a></span></li></ul>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492242.png" /></p>
<p class="maodian"><a name="_label2"></a></p><h2>安装 Mapster 相关包</h2>
<p class="maodian"><a name="_lab2_2_0"></a></p><h3>方式一、NuGet 包管理器安装</h3>
<p><span>在 NuGet 包管理器中搜索:</span><code>Mapster</code><span><span>&nbsp;和&nbsp;</span></span><code>Mapster.DependencyInjection</code><span><span><span>&nbsp;安装:</span></span></span></p>
<p><strong>Mapster 核心功能包</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492221.png" /></p>
<p><strong>Mapster.DependencyInjection 依赖注入集成包</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492280.png" /></p>
<p class="maodian"><a name="_lab2_2_1"></a></p><h3>方式二、.NET CLI 安装</h3>
<div class="jb51code"><pre class="brush:csharp;">dotnet add package Mapster --version 7.4.0 #核心功能包
dotnet add package Mapster.DependencyInjection --version 1.0.1 #依赖注入集成包</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>在 Program.cs 中注册 Mapster 服务</h2>
<div class="jb51code"><pre class="brush:csharp;">var builder = WebApplication.CreateBuilder(args);
// 注册 Mapster 服务
builder.Services.AddMapster();
// 注册 Mapster 映射规则
MapsterConfig.Register();</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>基础映射一行代码搞定</h2>
<p><span>接下来我们分别定义一个源对象(</span><code>Student</code><span><span>)和一个目标对象(</span></span><code>StudentViewModel</code><span><span><span>),它们的属性名和类型完全一致。</span></span></span></p>
<p class="maodian"><a name="_lab2_4_2"></a></p><h3>Student(源对象)&nbsp;&nbsp;&nbsp;&nbsp;</h3>
<div class="jb51code"><pre class="brush:csharp;">public classStudent
    {
      /// &lt;summary&gt;
      /// 学生ID [主键,自动递增]
      /// &lt;/summary&gt;
      
      
      publicint StudentID { get; set; }
      /// &lt;summary&gt;
      /// 班级ID
      /// &lt;/summary&gt;
      
      publicint ClassID { get; set; }
      /// &lt;summary&gt;
      /// 学生姓名
      /// &lt;/summary&gt;
      
      publicstring Name { get; set; }
      /// &lt;summary&gt;
      /// 学生年龄
      /// &lt;/summary&gt;
      
      publicint Age { get; set; }
      /// &lt;summary&gt;
      /// 学生性别
      /// &lt;/summary&gt;
      
      publicstring Gender { get; set; }
    }</pre></div>
<p class="maodian"><a name="_lab2_4_3"></a></p><h3>StudentViewModel(目标对象)&nbsp;&nbsp;&nbsp;&nbsp;</h3>
<div class="jb51code"><pre class="brush:csharp;">public classStudentViewModel
    {
      /// &lt;summary&gt;
      /// 学生ID
      /// &lt;/summary&gt;
      
      
      publicint StudentID { get; set; }
      /// &lt;summary&gt;
      /// 班级ID
      /// &lt;/summary&gt;
      
      publicint ClassID { get; set; }
      /// &lt;summary&gt;
      /// 学生姓名
      /// &lt;/summary&gt;
      
      publicstring Name { get; set; }
      /// &lt;summary&gt;
      /// 学生年龄
      /// &lt;/summary&gt;
      
      publicint Age { get; set; }
      /// &lt;summary&gt;
      /// 学生性别
      /// &lt;/summary&gt;
      
      publicstring Gender { get; set; }
      /// &lt;summary&gt;
      /// 班级名称
      /// &lt;/summary&gt;
      
      publicstring ClassName { get; set; }
    }</pre></div>
<p class="maodian"><a name="_lab2_4_4"></a></p><h3>Mapster 自动完成映射</h3>
<p><span>只要属性名和类型一致,Mapster 自动完成映射,无需任何配置!</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<div class="jb51code"><pre class="brush:csharp;">private async Task&lt;List&lt;StudentViewModel&gt;?&gt; GetStudentClassInfo(List&lt;Student&gt; students)
      {
            // Mapster 映射(无需任何配置!)
            var studentsListDto = students.Adapt&lt;List&lt;StudentViewModel&gt;&gt;();
            if (studentsListDto?.Count &gt; 0)
            {
                var classIDs = studentsListDto.Select(x =&gt; x.ClassID).Distinct().ToList();
                var querySchoolClassList = await _schoolClassHelper.QueryAsync(x =&gt; classIDs.Contains(x.ClassID)).ConfigureAwait(false);
                if (querySchoolClassList?.Count &gt; 0)
                {
                  foreach (var studentItem in studentsListDto)
                  {
                        var getClassInfo = querySchoolClassList.FirstOrDefault(x =&gt; x.ClassID == studentItem.ClassID);
                        if (getClassInfo != null)
                        {
                            studentItem.ClassName = getClassInfo.ClassName;
                        }
                  }
                }
            }
            return studentsListDto;
      }</pre></div>
<p><strong>映射结果输出:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492275.png" /></p>
<p class="maodian"><a name="_label5"></a></p><h2>自定义映射规则</h2>
<p><span>当属性名或类型不一致时,可通过配置指定映射逻辑。</span></p>
<p class="maodian"><a name="_lab2_5_5"></a></p><h3>UserInfo(源对象)</h3>
<div class="jb51code"><pre class="brush:csharp;">public classUserInfo
    {
      publicint Id { get; set; }
      publicstring FirstName { get; set; }
      publicstring LastName { get; set; }
      publicstring Email { get; set; }
      public DateTime CreatedAt { get; set; }
    }</pre></div>
<p class="maodian"><a name="_lab2_5_6"></a></p><h3>UserInfoViewModel(目标对象)&nbsp;&nbsp;&nbsp;&nbsp;</h3>
<div class="jb51code"><pre class="brush:csharp;">public classUserInfoViewModel
    {
      publicint Id { get; set; }
      /// &lt;summary&gt;
      /// 合并 FirstName + LastName
      /// &lt;/summary&gt;
      publicstring FullName { get; set; }
      publicstring Email { get; set; }
      /// &lt;summary&gt;
      /// 格式化日期
      /// &lt;/summary&gt;
      publicstring CreatedDate { get; set; }
    }</pre></div>
<p class="maodian"><a name="_lab2_5_7"></a></p><h3>配置 Mapster 映射规则</h3>
<p><span>在项目根目录创建&nbsp;</span><code>MapsterConfig.cs</code><span><span>:</span></span>&nbsp;&nbsp;&nbsp;&nbsp;</p>
<div class="jb51code"><pre class="brush:csharp;">/// &lt;summary&gt;
    /// Mapster 全局映射配置类。
    /// 用于集中注册项目中所有自定义的对象映射规则,
    /// 避免映射逻辑分散在各处,提升可维护性与可测试性。
    /// &lt;/summary&gt;
    publicstaticclassMapsterConfig
    {
      /// &lt;summary&gt;
      /// 注册所有自定义的 Mapster 映射配置
      /// 此方法应在应用程序启动时(如 Program.cs)调用一次
      /// &lt;/summary&gt;
      public static void Register()
      {
            TypeAdapterConfig&lt;UserInfo, UserInfoViewModel&gt;
                .NewConfig()
                .Map(dest =&gt; dest.FullName,
                     src =&gt; $"{src.FirstName} {src.LastName}".Trim())
                .Map(dest =&gt; dest.CreatedDate,
                     src =&gt; src.CreatedAt.ToString("yyyy-MM-dd"));
      }
    }</pre></div>
<p class="maodian"><a name="_lab2_5_8"></a></p><h3>自定义映射规则&nbsp;&nbsp;&nbsp;&nbsp;</h3>
<div class="jb51code"><pre class="brush:csharp;">/// &lt;summary&gt;
    /// 使用 Mapster 映射 UserInfo 示例
    /// &lt;/summary&gt;
   
    /")]
    publicclassUserInfoController : ControllerBase
    {
      privatereadonly IMapper _mapper;
      /// &lt;summary&gt;
      /// 依赖注入
      /// &lt;/summary&gt;
      /// &lt;param name="mapper"&gt;mapper&lt;/param&gt;
      public UserInfoController(IMapper mapper)
      {
            _mapper = mapper;
      }
      /// &lt;summary&gt;
      /// GetUserInfo
      /// &lt;/summary&gt;
      /// &lt;returns&gt;&lt;/returns&gt;
      
      public List&lt;UserInfoViewModel&gt; GetUserInfos()
      {
            var userInfos = new List&lt;UserInfo&gt;
            {
                new UserInfo
                {
                  Id = 999,
                  FirstName = "李",
                  LastName = "四",
                  Email = "lisi@qq.com",
                  CreatedAt = DateTime.Now.AddYears(-5)
                },
                new UserInfo
                {
                  Id = 666,
                  FirstName = "张",
                  LastName = "三",
                  Email = "zhangsan@example.com",
                  CreatedAt = DateTime.UtcNow.AddDays(-10)
                }
            };
            // 使用 Mapster 映射
            var getUserInfoViewModels = _mapper.Map&lt;List&lt;UserInfoViewModel&gt;&gt;(userInfos);
            return getUserInfoViewModels;
      }
    }</pre></div>
<p><strong>映射结果输出:</strong></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492222.png" /></p>
<p class="maodian"><a name="_label6"></a></p><h2>完整示例源代码</h2>
<ul><li><span><a href="https://github.com/YSGStudyHards/EasySQLite" rel="external nofollow" target="_blank">https://github.com/YSGStudyHards/EasySQLite</a></span></li></ul>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202510/2025102208492240.png" /></p>
頁: [1]
查看完整版本: 如何在 .NET 9 中使用 Mapster 快速、高效的实现对象映射