发布于2026-07-23 阅读(0)
扫一扫,手机访问
每个做.NET开发的,大概率都干过这事儿:从数据库捞出一堆实体,然后吭哧吭哧手动把它们赋值给DTO或者ViewModel。代码长得差不多,逻辑毫无技术含量,但这种重复劳动偏偏特别容易翻车——不是漏掉某个属性,就是手抖把字段名写错,再就是复制粘贴忘了改引用。项目小还好说,一旦业务复杂起来,这类“体力活”就成了效率黑洞。
那有没有办法让对象映射这件事变得丝滑一点?答案当然是肯定的。本文就围绕如何在ASP.NET Core 9.0 Web API项目里,用Mapster这个库来快速、高效地搞定对象映射,从根本上告别那些无意义的重复代码。
Mapster是一个开源免费的.NET对象映射库,基于MIT许可协议发布。它的核心卖点很直接:快速、高性能、灵活,同时使用起来相当顺手。用在项目里,可以大幅减少手动赋值带来的重复代码、人为错误和维护成本。
https://github.com/MapsterMapper/Mapster
https://github.com/MapsterMapper/Mapster/wiki

在NuGet包管理器里直接搜索下面这两个包,依次安装就行:
Mapster和
Mapster.DependencyInjection。
Mapster 核心功能包

Mapster.DependencyInjection 依赖注入集成包

用命令行安装也很简单,一条命令一个包:
dotnet add package Mapster --version 7.4.0 #核心功能包dotnet add package Mapster.DependencyInjection --version 1.0.1 #依赖注入集成包
安装完包之后,别忘了在Program.cs里把服务注册进去。代码量很少,两行搞定:
var builder = WebApplication.CreateBuilder(args);// 注册 Mapster 服务builder.Services.AddMapster();// 注册 Mapster 映射规则MapsterConfig.Register();
先看最简单的场景:源对象和目标对象的属性名和类型完全一致。这种情况下,Mapster几乎不需要你做任何配置,一行代码就能完成映射。
来个例子。定义一个 Student 类作为源对象,一个 StudentViewModel 作为目标对象:
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; } }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; } }注意,StudentViewModel比源对象多了个ClassName属性,不过这没关系——映射时按需赋值,剩下的手动处理就行。关键代码就这么一行:
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; }
映射结果输出:

感受一下,原来需要写一堆赋值语句的地方,现在一行 Adapt 就解决了。
当然,真实项目里不可能永远属性名一一对应。比如源对象里是 FirstName 和 LastName,但目标对象想要一个 FullName;源对象的 CreatedAt 是DateTime类型,目标对象的 CreatedDate 却想要字符串格式。这些场景就需要自定义映射规则了。
public classUserInfo { publicint Id { get; set; } publicstring FirstName { get; set; } publicstring LastName { get; set; } publicstring Email { get; set; } public DateTime CreatedAt { get; set; } }public classUserInfoViewModel { publicint Id { get; set; } /// /// 合并 FirstName + LastName /// publicstring FullName { get; set; } publicstring Email { get; set; } /// /// 格式化日期 /// publicstring CreatedDate { get; set; } }在项目根目录创建一个 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")); } }
然后在Controller里用起来:
////// 使用 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; } }
映射结果输出:

可以看到,FullName 自动拼接了姓和名,CreatedDate 也按自定义格式输出了。这种写法不仅清晰,而且映射逻辑集中管控,后期维护起来非常方便。
所有示例代码已开源,有需要可以直接参考:
https://github.com/YSGStudyHards/EasySQLite

售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8