AutoMapper

AutoMapper 使用实践

一.   使用意图

常常在开发过程中,碰到一个实体上的属性值,要赋值给另外一个相类似实体属性时,且属性有很多的情况。一般不利用工具的话,就要实例化被赋值实体B,然后再将实体A的字段一个个赋值给B的属性,单单写这些没有技术含量的赋值语句,就要用很大的代码篇幅。假如做得好一点的话,一般就是利用反射的方式,将A属性赋值给B,当然用反射的话,要顺利将A的属性,赋值B的属性,这样确实能够减少代码篇幅,那就要有一些约束或者限制,例如属性名称要相同,属性的数据类型要相同,这样反射起来才不费力。那如何使反射起来,更加灵活,可配置,且配置和反射过程能够分离,实现职责单一,AutoMapper 就是这样一个开源类库。

二.   认识AutoMapper

官方地址 :http://automapper.org/

GitHub 地址:https://github.com/AutoMapper/AutoMapper 包含AutoMapper 源代码与应用Simple。

开发指南:https://github.com/AutoMapper/AutoMapper/wiki/Getting-started

从我开发过程使用到一些场景

  1. 实体->实体
  2. 集合->集合
  3. 实体字段名称不同
  4. 实体数据类型不同
  5. 相同名称,相同数据类型无需配置
  6. Queryable Extensions ,也即支持Entity Framework

三.   最佳实践

AutoMapper开发指南,有详细的介绍,我这里就不再搬过说了,大家有空自己研究研究,我这里主要介绍一下AutoMapper比较好的实践方式,废话不多说,直接做项目给大家看。

  1. 项目结构

每个项目用途,解决方案文件夹基本标示清楚。

2. 以订单为例(不是真实业务,只是举个简单的例子),在Models 实体类库 新增OrderModel模型,在ViewModels 新增OrderViewModel模型,代码在下面

using System;
namespace Models
{
    public class OrderModel
    {
        public Guid OrderGuid { get; set; }

        public string OrderNo { get; set; }

        public string OrderCreator { get; set; }

        public DateTime OrderDateTime { get; set; }

        public string OrderStatus { get; set; }

        public string Description { get; set; }

        public string Creator { get; set; }

        public DateTime CreateDateTime { get; set; }

        public string LastModifier { get; set; }

        public DateTime LastModifiedDateTime { get; set; }
    }
}

using System;
namespace ViewModels
{
    public class OrderViewModel
    {
        public Guid OrderGuid { get; set; }

        public string OrderNo { get; set; }

        public string OrderCreator { get; set; }

        public DateTime OrderDateTime { get; set; }

        public string OrderStatus { get; set; }

        public string Description { get; set; }
    }
}

这里假设ViewModel,在使用过程中,不需要创建与修改相关的字段。

3. AutoMapper 配置

通过NuGet 程序包管理器,下载AutoMapper Dll,右键-》AutoMapperProfiles 类库-》管理NuGet程序包-》联机-》右上角搜索“AutoMapper” 下载安装

新增 ModelToViewModelProfile,ViewModelToModelProfile 两个配置类,继承AutoMapper 的 Profile 类,实现Configure重载方法,并分别引入Models & ViewModels 类库,ModelToViewModelProfile,ViewModelToModelProfile 代码如下

using AutoMapper;
using Models;
using ViewModels;

namespace AutoMapperProfiles
{
    public class ModelToViewModelProfile:Profile
    {
        protected override void Configure()
        {
            CreateMap<OrderModel, OrderViewModel>();
        }
    }
}

using AutoMapper;
using Models;
using ViewModels;

namespace AutoMapperProfiles
{
    public class ViewModelToModelProfile : Profile
    {
        protected override void Configure()
        {
            CreateMap<OrderViewModel, OrderModel>();
        }
    }
}

4.注册配置

在AutoMapperRegister 项目中,新增AutoMapperProfileRegister 类,按照 第3点,安装一下AutoMapper,同时引用AutoMapperProfiles 类库。代码如下

using AutoMapper;
using AutoMapperProfiles;

namespace AutoMapperRegister
{
    public class AutoMapperProfileRegister
    {
        public static void Register()
        {
            Mapper.Configuration.AddProfile(new ModelToViewModelProfile());
            Mapper.Configuration.AddProfile(new ViewModelToModelProfile());
        }
    }
}

5. 控制台验证是否能够顺利转换

按照 第3点,安装一下AutoMapper,引入 AutoMapperRegister ,Models,ViewModels Dll,编写测试代码,代码如下(见证奇迹的时候到了)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AutoMapper;
using AutoMapperRegister;
using Models;
using ViewModels;

namespace ConsoleAutoMapperSample
{
    class Program
    {
        static void Main(string[] args)
        {
            AutoMapperProfileRegister.Register();
            var order = new OrderModel
                            {
                                OrderGuid = Guid.NewGuid(),
                                OrderNo = "201604020001",
                                OrderCreator = "david",
                                OrderDateTime = DateTime.Now,
                                OrderStatus = "已出库",
                                Description = "请提供个人发票"
                            };

            var orderView = Mapper.Map<OrderModel, OrderViewModel>(order);
            orderView.OrderStatus = "已完成";

            var updateOrder = Mapper.Map<OrderViewModel, OrderModel>(orderView);
        }
    }
}

经过追踪对象属性变化,全部转换成功,不方便截图,稍后我会放出源代码。

最后源代码:

AutoMapperSample.zip

时间: 2024-10-07 13:00:37

AutoMapper的相关文章

使用AutoMapper实现Dto和Model的自由转换(上)

在实际的软件开发项目中,我们的"业务逻辑"常常需要我们对同样的数据进行各种变换.例如,一个Web应用通过前端收集用户的输入成为Dto,然后将Dto转换成领域模型并持久化到数据库中.另一方面,当用户请求数据时,我们又需要做相反的工作:将从数据库中查询出来的领域模型以相反的方式转换成Dto再呈现给用户.有时候我们还会面临更多的数据使用需求,例如有多个数据使用的客户端,每个客户端都有自己对数据结构的不同需求,而这也需要我们进行更多的数据转换. 频繁的数据转换琐碎而又凌乱,很多时候我们不得不:

使用AutoMapper实现Dto和Model的自由转换(中)

在上一篇文章中我们构造出了完整的应用场景,包括我们的Model.Dto以及它们之间的转换规则.下面就可以卷起袖子,开始我们的AutoMapper之旅了. [二]以Convention方式实现零配置的对象映射 我们的AddressDto和Address结构完全一致,且字段名也完全相同.对于这样的类型转换,AutoMapper为我们提供了Convention,正如它的官网上所说的: 引用 AutoMapper uses a convention-based matching algorithm to

使用AutoMapper实现Dto和Model的自由转换(下)

书接上文.在上一篇文章中我们讨论了使用AutoMapper实现类型间1-1映射的两种方式--Convention和Configuration,知道了如何进行简单的OO Mapping.在这个系列的最后一篇文章我想基于我们的需求讨论一些中级别的话题,包括:如何实现类型体型之间的映射,以及如何为两个类型实现多个映射规则. [四]将一个类型映射为类型体系 先回顾一下我们的Dto和Model.我们有BookDto,我们有Author,每个Author有自己的ContactInfo.现在提一个问题:如何从

对象映射工具AutoMapper介绍

AutoMapper是用来解决对象之间映射转换的类库.对于我们开发人员来说,写对象之间互相转换的代码是一件极其浪费生命的事情,AutoMapper能够帮助我们节省不少时间. 一. AutoMapper解决了什么问题? 要问AutoMapper解决了什么问题? 难道不是对象映射转换的问题吗? 当然是,不过我们可以问深入一些,为什么项目中会出现大量的对象映射转换?(以下对于非MVC项目也适用) 在现代的软件开发中,项目的层级更加的细分,而不同层级之间对于对象的需求是有区别的,这就需要在不同层级间传递

0.AutoMapper

AutoMapper是基于约定的对象 - 对象映射器.AutoMapper使用流畅的配置API来定义对象 - 对象映射策略.AutoMapper使用基于约定的匹配算法来匹配源到目标值.AutoMapper面向模型投影场景,将复杂的对象模型变成DTO和其他简单对象,这些对象的设计更适合于序列化,通信,消息传递或简单的域和应用程序层之间的防腐层. 1.扁平化 2.投影 3.配置验证 4.列表和数组 5.嵌套映射 6.自定义类型转换器 7.自定义值解析器 8.空替换 9.映射操作之前和之后 10.依赖

AutoMapper的介绍与使用(二)

AutoMapper的匹配 1,智能匹配 AutoMapper能够自动识别和匹配大部分对象属性: 如果源类和目标类的属性名称相同,直接匹配,不区分大小写 目标类型的CustomerName可以匹配源类型的Customer.Name 目标类型的Total可以匹配源类型的GetTotal()方法 2,自定义匹配 Mapper.CreateMap<CalendarEvent, CalendarEventForm>()                                          

升级AutoMapper后遇到的“Missing map”与“Missing type map configuration or unsupported mapping”问题

前几天发现 AutoMapper 3.3 的一个性能问题(详见:遭遇AutoMapper性能问题:映射200条数据比100条慢了近千倍),于是将 AutoMapper 升级至最新的 5.1.1 看是否也存在这个性能问题. 升级中想当然地将之前的map配置代码: Mapper.CreateMap<AEntity, ADto>(); Mapper.CreateMap<BEntity, BDto>(); 改为: Mapper.Initialize(cfg => cfg.Create

遭遇AutoMapper性能问题:映射200条数据比100条慢了近千倍

今天遇到了AutoMapper的一个性能问题,使用的是AutoMapper的Project特性,AutoMapper版本是3.3.0,代码如下: return await _repository .GetByStartId(startIngId, itemCount) .Project() .To<TDto>() .ToListAsync(); 当获取包含200条数据的列表时,竟然超过5秒. GetDocs(3000, 200) 6304ms GetDocs(3000, 200) 5822ms

分享一个简单程序(webApi+castle+Automapper+Ef+angular)

前段时间在周末给朋友做了一个小程序,用来记录他们单位的一些调度信息(免费,无版权问题).把代码分享出来.整个程序没有做任何架构.但是麻雀虽小,用到的技术也没少.WebApi+Castle+AutoMapper+Ef+angular,日志记录Log4net.初学者可以学习借鉴,虽然做的比较仓促,但是自我感觉代码写的还是比较规范. git地址:https://git.oschina.net/richieyangs/TaskRecord.git 只需修改web.config中的连接字符串,Ctrl+F

无名小卒AutoMapper的大显神威

最近在做gxpt(高校平台的项目),前台框架用的是MVC,后台用的是EF+WCF.怎么突然说出来感觉很高大上的样子.呵呵!但是在写代码的时候就发现一个问题.就是在EF中的实体(Model)跟前台需要的实体(DTO数据传输对象)是不一样的,所以就需要转换一下.一开始也没多想,可能是被做项目的热情冲昏了头脑,写多少代码都不觉得类,所以每当需要转换的时候就一个一个的写!给大家看一个例子! <span style="font-size:18px;">namespace testau