iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > ASP.NET >ASP.NETCore使用AutoMapper实现实体映射
  • 638
分享到

ASP.NETCore使用AutoMapper实现实体映射

2024-04-02 19:04:59 638人浏览 独家记忆
摘要

一、前言 在实际的项目开发过程中,我们使用各种ORM框架可以使我们快捷的获取到数据,并且可以将获取到的数据绑定到对应的List<T>中,然后页面或者接口直接显示List&

一、前言

在实际的项目开发过程中,我们使用各种ORM框架可以使我们快捷的获取到数据,并且可以将获取到的数据绑定到对应的List<T>中,然后页面或者接口直接显示List<T>中的数据。但是我们最终想要显示在视图或者接口中的数据和数据库实体之间可能存在着差异,一般的做法就是去创建一些对应的“模型”类,然后对获取到的数据再次进行处理,从而满足需求。

因此,如果便捷的实现数据库持久化对象与模型对象之间的实体映射,避免在去代码中手工实现这一过程,就可以大大降低开发的工作量。AutoMapper就是可以帮助我们实现实体转换过程的工具

二、使用AutoMapper实现实体映射

AutoMapper是一个OOM(Object-Object-Mapping)组件,从它的英文名字中可以看出,AutoMapper主要是为了实现实体间的相互转换,从而避免我们每次采用手工的方式进行转换。在没有OOM这类组件之前,如果我们需要实现实体之间的转换,只能使用手工修改代码,然后逐个赋值的方式实现映射,而有了OOM组件,可以很方便的帮助我们实现这一需求。看下面的一个例子。

首先创建一个ASP.net core webapi项目:

添加一个Student实体类:

namespace AutoMapperDemo.Model
{
    public class Student
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public int Age { get; set; }

        public string Gender { get; set; }
    }
}

添加StudentDTO类,跟Student属性一致。

然后添加一个类,模拟一些测试数据:

using AutoMapperDemo.Model;
using System.Collections.Generic;

namespace AutoMapperDemo
{
    public class Data
    {
        public static List<Student> ListStudent { get; set; }

        public static List<Student> GetList()
        {
            ListStudent = new List<Student>();
            for (int i = 0; i < 3; i++)
            {
                Student student = new Student() 
                {
                  ID=i,
                  Name=$"测试_{i}",
                  Age=20,
                  Gender="男"
                };
                ListStudent.Add(student);
            }

            return ListStudent;
        }
    }
}

添加Student控制器,通过Get方法获取所有的值:

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapperDemo.Model;
using Microsoft.Aspnetcore.mvc;

namespace AutoMapperDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        [HttpGet]
        public async Task<List<Student>> Get()
        {
            List<Student> list = new List<Student>();
            list = await Task.Run<List<Student>>(() => 
            {
                return Data.GetList();
            });
            return list;
        }
    }
}

使用Postman进行测试:

这样返回的数据直接就是数据库对应的实体类类型。这时需求改变了,我们要返回StudentDTO类型的数据,这时就需要修改代码:

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;
using Microsoft.AspNetCore.Mvc;

namespace AutoMapperDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        [HttpGet]
        public async Task<List<Student>> Get()
        {
            List<Student> list = new List<Student>();
            list = await Task.Run<List<Student>>(() => 
            {
                return Data.GetList();
            });


            return list;
        }

        [HttpGet("GetDTO")]
        public async Task<List<StudentDTO>> GetDto()
        {
            List<StudentDTO> list = new List<StudentDTO>();
            List<Student>  listStudent = await Task.Run<List<Student>>(() =>
            {
                return Data.GetList();
            });
            // 循环给属性赋值
            foreach (var item in listStudent)
            {
                StudentDTO dto = new StudentDTO();
                dto.ID = item.ID;
                dto.Name = item.Name;
                dto.Age = item.Age;
                dto.Gender = item.Gender;
                // 加入到集合中
                list.Add(dto);
            }

            return list;
        }
    }
}

还是使用Postman进行测试:

可以看到:这时返回的是DTO类型的数据。这种情况就是我们上面说的,需要手动修改代码,然后循环给对应的属性进行赋值。这里Student类只有4个属性,如果属性非常多,或者很多地方使用到了,如果还是采用这种方式进行赋值,那么就会很麻烦。假如以后其中的一个属性名称改变了,那么所有的地方也都需要修改,工作量就会很大。这时就需要使用AutoMapper解决。

首先引入AutoMapper包,直接在NuGet中引入:

这里选择安装AutoMapper.Extensions.Microsoft.DependencyInjection这个包。这个包主要是为了让我们可以通过依赖注入的方式去使用AutoMapper。

新建StudentProfile类,继承自AutoMapper的Profile类,在无参构造函数中,我们就可以通过 CreateMap 方法去创建两个实体间的映射关系。

using AutoMapper;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;

namespace AutoMapperDemo.AutoMapper
{
    /// <summary>
    /// 继承自Profile类
    /// </summary>
    public class StudentProfile: Profile
    {
        /// <summary>
        /// 构造函数中实现映射
        /// </summary>
        public StudentProfile()
        {
            // Mapping
            // 第一次参数是源类型(这里是Model类型),第二个参数是目标类型(这里是DTO类型)
            CreateMap<Student, StudentDTO>();
        }
    }
}

这里的 Profile有什么用呢?services.AddAutoMapper他会自动找到所有继承了Profile的类然后进行配置。

然后修改Student控制器,通过构造函数使用AutoMapper的注入,并使用AutoMapper实现自动映射:

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;
using Microsoft.AspNetCore.Mvc;

namespace AutoMapperDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        private readonly IMapper _mapper;

        /// <summary>
        /// 通过构造函数实现依赖注入
        /// </summary>
        /// <param name="mapper"></param>
        public StudentController(IMapper mapper)
        {
            _mapper = mapper;
        }

        [HttpGet]
        public async Task<List<Student>> Get()
        {
            List<Student> list = new List<Student>();
            list = await Task.Run<List<Student>>(() => 
            {
                return Data.GetList();
            });


            return list;
        }

        [HttpGet("GetDTO")]
        public async Task<List<StudentDTO>> GetDto()
        {
            List<StudentDTO> list = new List<StudentDTO>();
            List<Student>  listStudent = await Task.Run<List<Student>>(() =>
            {
                return Data.GetList();
            });
            //// 循环给属性赋值
            //foreach (var item in listStudent)
            //{
            //    StudentDTO dto = new StudentDTO();
            //    dto.ID = item.ID;
            //    dto.Name = item.Name;
            //    dto.Age = item.Age;
            //    dto.Gender = item.Gender;
            //    // 加入到集合中
            //    list.Add(dto);
            //}

            // 使用AutoMapper进行映射
            list = _mapper.Map<List<StudentDTO>>(listStudent);
            return list;
        }
    }
}

修改Startup类的ConfigureServices方法,添加AutoMapper:

public void ConfigureServices(IServiceCollection services)
{
    #region 使用AutoMapper
    // 参数类型是Assembly类型的数组 表示AutoMapper将在这些程序集数组里面遍历寻找所有继承了Profile类的配置文件
    // 在当前作用域的所有程序集里面扫描AutoMapper的配置文件
    services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
    #endregion

    services.AddControllers();
}

再次使用Postman进行测试:

可以看到,这样也实现了我们的需求,而且还不需要进行手动映射。

上面的示例中,Student和StudentDTO类里面的属性名称都是一样的,如果属性名称不一样呢?我们把StudentDTO类里面的ID改为StudentID,然后修改映射代码:

using AutoMapper;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;

namespace AutoMapperDemo.AutoMapper
{
    /// <summary>
    /// 继承自Profile类
    /// </summary>
    public class StudentProfile: Profile
    {
        /// <summary>
        /// 构造函数中实现映射
        /// </summary>
        public StudentProfile()
        {
            // Mapping
            // 第一次参数是源类型(这里是Model类型),第二个参数是目标类型(这里是DTO类型)
            // CreateMap<Student, StudentDTO>();

            // 使用自定义映射 Student类的ID映射到StudentDTO类的StudentID
            CreateMap<Student, StudentDTO>()
                .ForMember(destinationMember: des => des.StudentID, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.ID); });
        }
    }
}

再次使用Postman进行测试:

这样就实现了自定义映射。这里是映射了一个字段,如果是多个字段不同呢? 修改StudentDTO类:

namespace AutoMapperDemo.DTO
{
    public class StudentDTO
    {
        public int StudentID { get; set; }

        public string StudentName { get; set; }

        public int StudentAge { get; set; }

        public string StudentGender { get; set; }
    }
}

然后修改映射配置类:

using AutoMapper;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;

namespace AutoMapperDemo.AutoMapper
{
    /// <summary>
    /// 继承自Profile类
    /// </summary>
    public class StudentProfile: Profile
    {
        /// <summary>
        /// 构造函数中实现映射
        /// </summary>
        public StudentProfile()
        {
            // Mapping
            // 第一次参数是源类型(这里是Model类型),第二个参数是目标类型(这里是DTO类型)
            // CreateMap<Student, StudentDTO>();

            // 使用自定义映射 Student类的ID映射到StudentDTO类的StudentID
            //CreateMap<Student, StudentDTO>()
            //    .ForMember(destinationMember: des => des.StudentID, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.ID); });

            // 对多个属性进行自定义映射
            CreateMap<Student, StudentDTO>()
                .ForMember(destinationMember: des => des.StudentID, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.ID); })
                .ForMember(destinationMember: des => des.StudentName, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.Name); })
                .ForMember(destinationMember: des => des.StudentAge, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.Age); })
                .ForMember(destinationMember: des => des.StudentGender, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.Gender); });
        }
    }
}

在使用Postman进行测试:

这样就实现了多个属性的自定义映射。 

上面的实例中是从Student映射到StudentDTO,那么可以从StudentDTO映射到Student吗?答案是肯定的,只需要在映射的最后使用ReverseMap()方法即可:

using AutoMapper;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;

namespace AutoMapperDemo.AutoMapper
{
    /// <summary>
    /// 继承自Profile类
    /// </summary>
    public class StudentProfile: Profile
    {
        /// <summary>
        /// 构造函数中实现映射
        /// </summary>
        public StudentProfile()
        {
            // Mapping
            // 第一次参数是源类型(这里是Model类型),第二个参数是目标类型(这里是DTO类型)
            // CreateMap<Student, StudentDTO>();

            // 使用自定义映射 Student类的ID映射到StudentDTO类的StudentID
            //CreateMap<Student, StudentDTO>()
            //    .ForMember(destinationMember: des => des.StudentID, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.ID); });

            // 对多个属性进行自定义映射
            CreateMap<Student, StudentDTO>()
                .ForMember(destinationMember: des => des.StudentID, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.ID); })
                .ForMember(destinationMember: des => des.StudentName, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.Name); })
                .ForMember(destinationMember: des => des.StudentAge, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.Age); })
                .ForMember(destinationMember: des => des.StudentGender, memberOptions: opt => { opt.MapFrom(mapExpression: map => map.Gender); })
                // ReverseMap表示双向映射
                .ReverseMap();
        }
    }
}

我们修改Data,里面增加一个Add方法,可以将Student添加到集合中:

using AutoMapperDemo.Model;
using System.Collections.Generic;

namespace AutoMapperDemo
{
    public class Data
    {
        public static List<Student> ListStudent { get; set; }

        static Data()
        {
            ListStudent = new List<Student>();
            for (int i = 0; i < 3; i++)
            {
                Student student = new Student()
                {
                    ID = i,
                    Name = $"测试_{i}",
                    Age = 20,
                    Gender = "男"
                };
                ListStudent.Add(student);
            }
        }

        public static List<Student> GetList()
        {
            return ListStudent;
        }

        public static void Add(Student entity)
        {
            ListStudent.Add(entity);
        }
    }
}

修改Student控制器,添加一个Post方法,传入的参数的StudentDTO类型:

using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapperDemo.DTO;
using AutoMapperDemo.Model;
using Microsoft.AspNetCore.Mvc;

namespace AutoMapperDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StudentController : ControllerBase
    {
        private readonly IMapper _mapper;

        /// <summary>
        /// 通过构造函数实现依赖注入
        /// </summary>
        /// <param name="mapper"></param>
        public StudentController(IMapper mapper)
        {
            _mapper = mapper;
        }

        [HttpGet]
        public async Task<List<Student>> Get()
        {
            List<Student> list = new List<Student>();
            list = await Task.Run<List<Student>>(() => 
            {
                return Data.GetList();
            });


            return list;
        }

        [HttpGet("GetDTO")]
        public async Task<List<StudentDTO>> GetDto()
        {
            List<StudentDTO> list = new List<StudentDTO>();
            List<Student>  listStudent = await Task.Run<List<Student>>(() =>
            {
                return Data.GetList();
            });
            //// 循环给属性赋值
            //foreach (var item in listStudent)
            //{
            //    StudentDTO dto = new StudentDTO();
            //    dto.ID = item.ID;
            //    dto.Name = item.Name;
            //    dto.Age = item.Age;
            //    dto.Gender = item.Gender;
            //    // 加入到集合中
            //    list.Add(dto);
            //}

            // 使用AutoMapper进行映射
            list = _mapper.Map<List<StudentDTO>>(listStudent);
            return list;
        }

        [HttpPost]
        public async Task<List<Student>> Post([FromBody]StudentDTO entity)
        {
            List<Student> list = new List<Student>();
            // 将StudentDTO反向映射为Student类型
            Student student = _mapper.Map<Student>(entity);
            // 添加到集合中
            Data.Add(student);
            // 返回增加后的数组,这里返回Student
            list = await Task.Run<List<Student>>(() =>
            {
                return Data.GetList();
            });


            return list;
        }
    }
}

使用Postman进行测试:

返回结果:

这样就实现了映射的反转。

具体其它API功能,参考AutoMapper官网:https://automapper.readthedocs.io/en/latest/index.html

到此这篇关于ASP.net core使用AutoMapper实现实体映射的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: ASP.NETCore使用AutoMapper实现实体映射

本文链接: https://www.lsjlt.com/news/143924.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • ASP.NETCore使用AutoMapper实现实体映射
    一、前言 在实际的项目开发过程中,我们使用各种ORM框架可以使我们快捷的获取到数据,并且可以将获取到的数据绑定到对应的List<T>中,然后页面或者接口直接显示List&...
    99+
    2024-04-02
  • ASP.NET Core如何使用AutoMapper实现实体映射
    这篇文章将为大家详细讲解有关ASP.NET Core如何使用AutoMapper实现实体映射,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、前言在实际的项目开发过程中,我们使用各种ORM框架可...
    99+
    2023-06-29
  • AutoMapper实体映射基本用法
    目录AutoMapper安装AutoMapper 基本使用映射配置映射检查性能Profile 配置依赖注入表达式与 DTOAutoMapper安装 在 Nuget 搜索即可安装,目前...
    99+
    2024-04-02
  • Automapper实现自动映射的实例代码
    出于安全考虑,在后台与前台进行数据传输时,往往不会直接传输实体模型,而是使用Dto(Data transfer object 数据传输对象),这样在后台往前台传递数据时可以省略不必要的信息,只保留必要的信息,大大增强数据安全性。下面给出两个...
    99+
    2023-05-31
    automapper 映射 pp
  • 如何使用对象到对象映射AutoMapper
    本篇内容主要讲解“如何使用对象到对象映射AutoMapper”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用对象到对象映射AutoMapper”吧!入门A...
    99+
    2024-04-02
  • ASP.NET Core扩展库之实体映射使用详解
    目录一、启用二、配置自定义转换逻辑三、使用四、通过特性指定属性映射关系五、拷贝六、示例在分层设计模式中,各层之间的数据通常通过数据传输对象(DTO)来进行数据的传递,而大多数情况下,...
    99+
    2024-04-02
  • Java实体映射工具MapStruct使用方法详解
    目录1.序 2.简单用例 3.使用详解 1)关于接口注解@Mapper几种属性用法详解 2) 其他方法级别注解 总结1.序 通常在后端开发中经常不直接返回实体Entity类,经过处...
    99+
    2024-04-02
  • 使用nginx实现端口映射的教程
    这篇文章主要讲解了“使用nginx实现端口映射的教程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“使用nginx实现端口映射的教程”吧!考虑这样一个场景,我们部署了若干web应用在一台云服务...
    99+
    2023-06-04
  • mybatis映射怎么实现
    这篇文章主要介绍“mybatis映射怎么实现”,在日常操作中,相信很多人在mybatis映射怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”mybatis映射怎么实现”的疑惑有所帮助!接下来,请跟着小编...
    99+
    2023-06-04
  • php如何实现映射
    小编给大家分享一下php如何实现映射,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!映射映射,或者射影,在数学及相关的领域经常等同于函数。基于此,部分映射就相当于部...
    99+
    2023-06-06
  • golang实现内存映射
    Go语言作为一门现代化的编程语言,已经成为了Web开发、网络编程、云计算等领域的热门选择。其中Go语言在内存管理方面的特性非常强大,因此许多开发者也喜欢使用Go语言开发高性能、高可用性的应用程序。而内存映射是Go语言中非常有趣的一个特性,本...
    99+
    2023-05-14
  • Hibernate映射怎么实现
    这篇文章主要讲解了“Hibernate映射怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Hibernate映射怎么实现”吧!我曾对Hibernate有很深刻的印象,但我遇到的一个问题...
    99+
    2023-06-17
  • 如何使用AutoMapper实现GET请求
    这篇文章主要讲解了“如何使用AutoMapper实现GET请求”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用AutoMapper实现GET请求”吧!需求需求很简单:实现GET请求获取...
    99+
    2023-06-22
  • java怎么从clob字段映射实体类
    要从CLOB字段映射到Java实体类,可以按照以下步骤进行操作:1. 首先,创建一个Java实体类,用于表示CLOB字段的数据。例如...
    99+
    2023-10-18
    java
  • SpringDataJPA实体类关系映射配置方式
    目录SpringDataJPA1.单向一对一映射2.双向一对一映射3.单向一对多映射4.双向一对多映射5.单向多对一映射6.双向多对一映射7.单向多对多映射8.双向多对多映射Spri...
    99+
    2024-04-02
  • Java使用HashMap映射实现消费抽奖功能
    本文实例为大家分享了Java实现消费抽奖功能的具体代码,供大家参考,具体内容如下 要求如下: 1、定义奖项类Awards,包含成员变量String类型的name(奖项名称)和int类...
    99+
    2024-04-02
  • python实现两字符串映射
    目录python两字符串映射python字符映射表和字符替换python两字符串映射题目:pattern = "abba",s="dog cat cat dog"---->Truepattern...
    99+
    2024-04-02
  • LINQ to SQL映射怎么实现
    本篇内容介绍了“LINQ to SQL映射怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!LINQ to SQL映射函数和存储过程LI...
    99+
    2023-06-17
  • Golang结构体映射mapstructure库怎么使用
    这篇文章主要介绍“Golang结构体映射mapstructure库怎么使用”,在日常操作中,相信很多人在Golang结构体映射mapstructure库怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”G...
    99+
    2023-07-04
  • Spring Data JPA映射怎么自定义实体类
    这篇文章主要介绍“Spring Data JPA映射怎么自定义实体类”,在日常操作中,相信很多人在Spring Data JPA映射怎么自定义实体类问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
    99+
    2023-06-25
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作