当前位置: 首页 > news >正文

.NET 中的新增功能系列文章—— .NET MAUI 中的新增功能

痰洞南牌前言

Mapster 介绍

安装 Mapster 相关包

在 Program.cs 中注册 Mapster 服务

基础映射一行代码搞定

自定义映射规则

完整示例源代码

image

前言

在日常开发中,我们常常需要将一个对象映射到另一个对象,比如将数据库实体转换为数据传输对象(DTO),或将请求模型映射为领域模型。这个过程通常涉及大量重复性代码,如果每次都手动编写,不仅严重影响开发效率,而且随着项目规模不断增长,还容易出现错误(如:属性遗漏、手写时写错或复制粘贴失误等)。

本文我们的主要内容就是讲解如何在 ASP.NET Core 9.0 Web API 项目中使用 Mapster 快速、高效的实现对象映射。

Mapster 介绍

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

安装 Mapster 相关包

方式一、NuGet 包管理器安装

在 NuGet 包管理器中搜索:Mapster 和 Mapster.DependencyInjection 安装:

Mapster 核心功能包

image

Mapster.DependencyInjection 依赖注入集成包

image

方式二、.NET CLI 安装

dotnet add package Mapster --version 7.4.0 #核心功能包

dotnet add package Mapster.DependencyInjection --version 1.0.1 #依赖注入集成包

在 Program.cs 中注册 Mapster 服务

var builder = WebApplication.CreateBuilder(args);

// 注册 Mapster 服务

builder.Services.AddMapster();

// 注册 Mapster 映射规则

MapsterConfig.Register();

基础映射一行代码搞定

接下来我们分别定义一个源对象(Student)和一个目标对象(StudentViewModel),它们的属性名和类型完全一致。

Student(源对象)

public classStudent

{

///

/// 学生ID [主键,自动递增]

///

[PrimaryKey, AutoIncrement]

[Display(Name = "学生ID")]

publicint StudentID { get; set; }

///

/// 班级ID

///

[Display(Name = "班级ID")]

publicint ClassID { get; set; }

///

/// 学生姓名

///

[Display(Name = "学生姓名")]

publicstring Name { get; set; }

///

/// 学生年龄

///

[Display(Name = "学生年龄")]

publicint Age { get; set; }

///

/// 学生性别

///

[Display(Name = "学生性别")]

publicstring Gender { get; set; }

}

StudentViewModel(目标对象)

public classStudentViewModel

{

///

/// 学生ID

///

[PrimaryKey, AutoIncrement]

[Display(Name = "学生ID")]

publicint StudentID { get; set; }

///

/// 班级ID

///

[Display(Name = "班级ID")]

publicint ClassID { get; set; }

///

/// 学生姓名

///

[Display(Name = "学生姓名")]

publicstring Name { get; set; }

///

/// 学生年龄

///

[Display(Name = "学生年龄")]

publicint Age { get; set; }

///

/// 学生性别

///

[Display(Name = "学生性别")]

publicstring Gender { get; set; }

///

/// 班级名称

///

[Display(Name = "班级名称")]

publicstring ClassName { get; set; }

}

Mapster 自动完成映射

只要属性名和类型一致,Mapster 自动完成映射,无需任何配置!

private async Task?> GetStudentClassInfo(List students)

{

// Mapster 映射(无需任何配置!)

var studentsListDto = students.Adapt>();

if (studentsListDto?.Count > 0)

{

var classIDs = studentsListDto.Select(x => x.ClassID).Distinct().ToList();

var querySchoolClassList = await _schoolClassHelper.QueryAsync(x => classIDs.Contains(x.ClassID)).ConfigureAwait(false);

if (querySchoolClassList?.Count > 0)

{

foreach (var studentItem in studentsListDto)

{

var getClassInfo = querySchoolClassList.FirstOrDefault(x => x.ClassID == studentItem.ClassID);

if (getClassInfo != null)

{

studentItem.ClassName = getClassInfo.ClassName;

}

}

}

}

return studentsListDto;

}

映射结果输出:

image

自定义映射规则

当属性名或类型不一致时,可通过配置指定映射逻辑。

UserInfo(源对象)

public classUserInfo

{

publicint Id { get; set; }

publicstring FirstName { get; set; }

publicstring LastName { get; set; }

publicstring Email { get; set; }

public DateTime CreatedAt { get; set; }

}

UserInfoViewModel(目标对象)

public classUserInfoViewModel

{

publicint Id { get; set; }

///

/// 合并 FirstName + LastName

///

publicstring FullName { get; set; }

publicstring Email { get; set; }

///

/// 格式化日期

///

publicstring CreatedDate { get; set; }

}

配置 Mapster 映射规则

在项目根目录创建 MapsterConfig.cs:

///

/// Mapster 全局映射配置类。

/// 用于集中注册项目中所有自定义的对象映射规则,

/// 避免映射逻辑分散在各处,提升可维护性与可测试性。

///

publicstaticclassMapsterConfig

{

///

/// 注册所有自定义的 Mapster 映射配置

/// 此方法应在应用程序启动时(如 Program.cs)调用一次

///

public static void Register()

{

TypeAdapterConfig

.NewConfig()

.Map(dest => dest.FullName,

src => $"{src.FirstName} {src.LastName}".Trim())

.Map(dest => dest.CreatedDate,

src => src.CreatedAt.ToString("yyyy-MM-dd"));

}

}

自定义映射规则

///

/// 使用 Mapster 映射 UserInfo 示例

///

[ApiController]

[Route("api/[controller]/[action]")]

publicclassUserInfoController : ControllerBase

{

privatereadonly IMapper _mapper;

///

/// 依赖注入

///

///mapper

public UserInfoController(IMapper mapper)

{

_mapper = mapper;

}

///

/// GetUserInfo

///

///

[HttpGet]

public List GetUserInfos()

{

var userInfos = new List

{

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>(userInfos);

return getUserInfoViewModels;

}

}

映射结果输出:

image

完整示例源代码

https://github.com/YSGStudyHards/EasySQLite

image

http://www.jsqmd.com/news/439218/

相关文章:

  • 2026年湖南有实力的代理记账专业公司推荐,服务区域覆盖长沙 - mypinpai
  • 震撼!CloseAI终于变回OpenAI了!GPT-OSS来了,这次真的不一样了
  • 用Blender制作C919飞机:从层级关系到3D建模的实战指南
  • 破解无锡公司注册痛点:‘无忧注册四力模型’如何让创业第一步就赢? - 速递信息
  • 【深度解析】公司注销服务:从合规逻辑到高效实践的全维度科普 - 速递信息
  • 电商、社媒必看:如何高效使用动态代理IP实现多账号管理
  • 瑞祥商联卡用不上?这样回收超划算 - 畅回收小程序
  • 2026年资质齐全的玻璃外墙清洗公司怎么选,看看排名就知道 - myqiye
  • C++底层机制(3):move / forward / 完美转发 一张图讲透
  • 2026四川乡村旅游品牌排名,东越天池凭特色仙人掌产品上榜 - 工业设备
  • Apache SeaTunnel 要不要升?怎么升?一文讲透 2.x 升级 7 个关键点
  • 2026年京津冀地区门墙柜一体定制专业供应商排名,哪家更靠谱? - 工业推荐榜
  • Flink REST API 不用进 Web UI,也能查作业、打 Checkpoint、触发 Savepoint、看 Watermark
  • 2026年中国房产继承律师电话查询推荐:解决继承难题的帮手 - 品牌推荐
  • 测试用的
  • 2026年诚信的轻质仿石幕墙板厂家优质供应商推荐榜 - 品牌鉴赏师
  • 【鸿蒙游戏技术分享 第78期】游戏无法登录,game service kit返回报错1002000001 system internal error
  • 深聊校园联合招聘,云南立才企业管理有限公司优势知多少 - 工业品网
  • 什么洗发水好用?2026年热门洗护品牌深度测评 - 包罗万闻
  • 2026年3月立式内圆磨厂家推荐:行业测评与选择指南 - 品牌鉴赏师
  • 2026深圳市殡仪服务企业优质推荐 专业靠谱的治丧服务之选 - 深度智识库
  • 2026年天津婚姻纠纷律师电话查询推荐:服务特色与选择建议 - 品牌推荐
  • 2026年中国房产继承律师电话查询推荐:精选推荐与使用指南 - 品牌推荐
  • 2026年主流AI财务软件全景盘点与选型建议 - 速递信息
  • 2026 年 2 月河北墓碑/墓碑设计加工与制作/墓区规划设计/石制品加工/园林雕塑/石雕厂家综合实力深度分析报告 - 2026年企业推荐榜
  • 2026年市面上口碑好的冷挤压成型液压机厂家推荐榜单,精密冷挤压/冷挤压成型/金属挤压成型,冷挤压成型液压机哪里有卖 - 品牌推广师
  • 天猫超市购物卡超值回收攻略 - 团团收购物卡回收
  • 揭秘盒马鲜生购物卡回收,轻松变现! - 团团收购物卡回收
  • 2026年比较好的釉面发泡陶瓷保温板厂家推荐及选购参考榜 - 品牌鉴赏师
  • 2026年诚信的轻质干挂石材,干挂轻质石材,仿石材干挂板厂家推荐及选购指南 - 品牌鉴赏师