对象映射工具AutoMapper介绍
AutoMapper是用来解决对象之间映射转换的类库。对于我们开发人员来说,写对象之间互相转换的代码是一件极其浪费生命的事情,AutoMapper能够帮助我们节省不少时间。
一. AutoMapper解决了什么问题?
要问AutoMapper解决了什么问题? 难道不是对象映射转换的问题吗?
当然是,不过我们可以问深入一些,为什么项目中会出现大量的对象映射转换?(以下对于非MVC项目也适用)
在现代的软件开发中,项目的层级更加的细分,而不同层级之间对于对象的需求是有区别的,这就需要在不同层级间传递数据的时候,必须要转换数据。
举一些实际具体的例子:
在持久层(数据访问层), 我们的User对象,可能是一个包含User表中所有字段的数据的对象,甚至包含了用户的Password信息。而在界面层,我们只是需要显示用户的name, email,不需要Password这些额外的信息,同时,它还需要用户的考勤信息,而这个信息来自于另外一张表。
这个例子中,能够发现不同层之间,我们对于数据对象的需求是不同的。
每个层都做了它们职责范围内的事情:
持久层关注数据,所以只提供数据对象,它无需知道外层如何使用这些数据对象,也无法知道。
界面层关注数据的呈现,它只关注它要显示的数据。
那么问题是,谁来弥补它们之间的鸿沟?DTO(Data Transfer Object)——数据传输对象。而AutoMapper就是解决其中涉及到的数据对象转换的工具。

在实际开发中,如果你还可以直接在Business层或者界面层直接使用持久层的对象,因为你认为这个关系不大,整个项目都是你自己控制的,虽然dirty,但是quick. 作为一个有些洁癖的程序员,我还是建议使用DTO在不同层级之间传递数据。因为当你做更高层级开发的时候,比如开发web service,WCF,Web API这些为系统外部提供接口的开发时候,你就回明白这些好的习惯和思维能够帮助你更加好的设计这些外部接口。
二. AutoMapper如何使用?
先来看一个简单的例子,这个例子是定义Order对象到OrderDto对象之间的映射。(我们把Order称呼为源类,OrderDto称呼为目标类)
Mapper.CreateMap<Order, OrderDto>();//创建映射关系Order –> OrderDto
OrderDto dto = Mapper.Map<OrderDto>(order);//使用Map方法,直接将order对象装换成OrderDto对象
智能匹配
AutoMapper能够自动识别和匹配大部分对象属性:
- 如果源类和目标类的属性名称相同,直接匹配
- 目标类型的CustomerName可以匹配源类型的Customer.Name
- 目标类型的Total可以匹配源类型的GetTotal()方法
自定义匹配规则
AutoMapper还支持自定义匹配规则
Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
//属性匹配,匹配源类中WorkEvent.Date到EventDate
.ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.WorkEvent.Date))
.ForMember(dest => dest.SomeValue, opt => opt.Ignore())//忽略目标类中的属性
.ForMember(dest => dest.TotalAmount, opt => opt.MapFrom(src => src.TotalAmount ?? ))//复杂的匹配
.ForMember(dest => dest.OrderDate, opt => opt.UserValue<DateTime>(DateTime.Now));固定值匹配
测试
当定义完规则后,可以使用下面的代码来验证配置是否正确。不正确抛出异常AutoMapperConfigurationException.
Mapper.AssertConfigurationIsValid();
三. AutoMapper处理多对一映射
我们开篇提到的问题中,说到界面显示User的name, email, 还有用户的考勤信息,而这些信息来自于2张不同的表。这就涉及到了多对一映射的问题,2个持久层对象需要映射到一个界面显示层的对象。
假设我们的持久层对象是这样的:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Passworkd { get; set; }
public DateTime Birthday { get; set; }
} public class Evaluation
{
public int Id { get; set; }
public int Score { get; set; }
}
在Asp.net MVC中,我的界面显示层的ViewModel是这样的
public class UserViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Score { get; set; }
}
接下来,为了达到多对一的映射的目的,我们创建这个EntityMapper类
public static class EntityMapper
{
public static T Map<T>(params object[] sources) where T : class
{
if (!sources.Any())
{
return default(T);
} var initialSource = sources[];
var mappingResult = Map<T>(initialSource); // Now map the remaining source objects
if (sources.Count() > )
{
Map(mappingResult, sources.Skip().ToArray());
}
return mappingResult;
} private static void Map(object destination, params object[] sources)
{
if (!sources.Any())
{
return;
}
var destinationType = destination.GetType();
foreach (var source in sources)
{
var sourceType = source.GetType();
Mapper.Map(source, destination, sourceType, destinationType);
}
} private static T Map<T>(object source) where T : class
{
var destinationType = typeof(T);
var sourceType = source.GetType();
var mappingResult = Mapper.Map(source, sourceType, destinationType);
return mappingResult as T;
}
}
为了实现多个源对象映射一个目标对象,我们使用了AutoMapper的方法,从不同的源对象逐一匹配一个已经存在的目标对象。下面是实际使用在MVC中的代码:
public ActionResult Index()
{
var userId = ,
var user = _userRepository.Get(userId);
var score = _scoreRepository.GetScore(userId);
var userViewModel = EntityMapper.Map<UserViewModel>(user, score);
return this.View(userViewModel);
}
四. 使用Profile在Asp.net MVC项目中配置AutoMapper
Profile是AutoMapper中用来分离类型映射定义的,这样可以让我们的定义AutoMapper类型匹配的代码可以更加分散,合理和易于管理。
利用Profile, 我们可以更加优雅的在MVC项目中使用我们的AutoMapper. 下面是具体的方法:
1. 在不同层中定义Profile,只定义本层中的类型映射
继承AutoMapping的Profile类,重写ProfileName属性和Configure()方法。
public class ViewModelMappingProfile: Profile
{
public override string ProfileName
{
get
{
return GetType().Name;
}
} protected override void Configure()
{
Mapper.CreateMap......
}
}
2. 创建AutoMapperConfiguration, 提供静态方法Configure,一次加载所有层中Profile定义
public class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(x => x.AddProfile<ViewModelMappingProfile>());
Mapper.AssertConfigurationIsValid();
}
}
3. 在Global.cs文件中执行
最后,在Global.cs文件中程序启动前,调用该方法
AutoMapperConfiguration.Configuration()
对象映射工具AutoMapper介绍的更多相关文章
- .NET的对象映射工具AutoMapper使用笔记
AutoMapper是一个.NET的对象映射工具. 项目地址:https://github.com/AutoMapper/AutoMapper. 帮助文档:https://github.com/Aut ...
- EF架构~AutoMapper对象映射工具简化了实体赋值的过程
回到目录 AutoMapper是一个.NET的对象映射工具,一般地,我们进行面向服务的开发时,都会涉及到DTO的概念,即数据传输对象,而为了减少系统的负载,一般我们不会把整个表的字段作为传输的数据,而 ...
- .NET之AutoMapper对象映射工具运用
AutoMapper对象映射工具:主要是将某一个实体转成另一个实体. 1.引用NuGet包;搜索:AutoMapper 2.创建实体类 using System; using System.Colle ...
- .NET的DTO映射工具AutoMapper
.NET的DTO映射工具AutoMapper 原文:https://github.com/AutoMapper/AutoMapper/wiki/Getting-started 参考:http://ww ...
- 【5min+】 对象映射只有AutoMapper?试试Mapster
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- 对象转换工具 MapStruct 介绍
前言 在我们日常开发的分层结构的应用程序中,为了各层之间互相解耦,一般都会定义不同的对象用来在不同层之间传递数据,因此,就有了各种 XXXDTO.XXXVO.XXXBO 等基于数据库对象派生出来的对象 ...
- ASP.NET Core 中的对象映射之 AutoMapper
目录 AutoMapper 简介 AutoMapper 使用 初始化 Profile设置 扁平化映射 集合映射 投影 条件映射 值转换 设置转换前后行为 配置验证及设置 反向映射 自定义转换器 自定义 ...
- [转]对象映射类AutoMapper的使用
由于原文太长了,此处就直接贴上原文的超链接,大家自行学习. codeproject中的一篇文章: AutoMapper
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
上一篇文章(https://www.cnblogs.com/meowv/p/12961014.html)集成了定时任务处理框架Hangfire,完成了一个简单的定时任务处理解决方案. 本篇紧接着来玩一 ...
随机推荐
- EntityFramework 7 OrderBy Skip Take-计算排序分页 SQL 翻译
先解释一下这个标题的意思,OrderBy 在 Linq 语句中,我们经常使用,比如 OrderBy(b => b.BlogId) 就是对 BlogId 字段进行升序排序,这是针对一个字段的排序, ...
- objective-c 语法快速过(6)内存管理原理
内存管理基本原理(最重要) 移动设备的内存极其有限(iphone 4内存512M),每个app所能占用的内存是有限制的(几十兆而已). 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不 ...
- M端总结
最近在项目开发过程中涉及到了移动端,现在对此进行总结. 在此次M端的开发过程中,遇到了许多问题,在此进行一次总结,希望大家在以后的开发过程中能尽量规避类似的问题,提高开发效率和代码质量.一.布局1.移 ...
- 奇妙的NULL值,你知道多少
<NULL值的多义性分析> 谈到NULL值,很多人都是很熟悉,但是深入了解后,又感觉到陌生,对其含义和用法,都无法很准确的理解.NULL在数据库和编程语言中,存在的意义和附带的含义不同. ...
- 企业 SOA 设计(1)–ESB 设计
最近为公司完成了一个 ESB 的设计.下面简要说明一下具体的设计方案. 企业 SOA 整体方案 在前一篇<SOA.ESB.NServiceBus.云计算 总结>中说到,SOA 是面向服 ...
- HtmlHelper拓展实现RadioList
mvc中HtmlHelper可以帮助我们生成许多Html控件,但是没有类似DropDownList的RadioList,但是发现这些方法都是拓展方法,于是就想自己也拓展一个RadioList 从网上下 ...
- html的留言板制作(js)
这次留言板运用到了最基础的localstorage的本地存储,展现的效果主要有: 1.编写留言2.留言前可以编辑自己的留言昵称.不足之处: 1.未能做出我喜欢的类似于网易的叠楼功能. 2.未能显示评论 ...
- 异构(兼容dubbo)SOA系统架构(.net)优化升级
前面一片文章已经提到我司的异构(兼容dubbo)SOA系统架构,解决了不少技术痛点,也还算比较完善,也顺利推广开来. 但作为项目的开发者,自己产品的问题心里是清楚的,离自己满意还是有不小的距离. 在推 ...
- 移动端API架构 统一Proxy还是各自为政?
今天首先回答上一篇的问题: 为什么APP通过运营商接入网络,连通率会那么差? 1. 域名缓存问题 运营商的localdns会缓存域名的解析结果,不向权威DNS递归查询解析 为什么要这么干呢? 1)运营 ...
- super.getClass()方法调用
下面程序的输出结果是多少?import java.util.Date;public class Test extends Date{public static void main(String[] a ...