AutoMapper(一)
返回总目录
映射前后操作
偶尔有时候,在映射发生之前或之后,你可能需要执行一些自定义的逻辑。这可能是很少见的事情,因为在AutoMapper之外处理这些事情是更明显的。你可以创建一个映射前后的全局操作:
Mapper.CreateMap<Source, Dest>()
.BeforeMap((src, dest) => src.Value = src.Value + )
.AfterMap((src, dest) => dest.Name = "John");
或者在映射期间,创建映射前后的回调函数:
int i = ;
Mapper.Map<Source, Dest>(src, opt => {
opt.BeforeMap((src, dest) => src.Value = src.Value + i);
opt.AfterMap((src, dest) => dest.Name = HttpContext.Current.Identity.Name);
});
当你需要将上下文信息注入映射前后的行为中时,后者的配置很有用。
条件映射
在属性映射之前,AutoMapper允许将必须满足的条件添加到属性上。
这个用在下面这种情况,比如有两个类,分别是Aliens(外星人)和Person(人)类,都有一个Age属性,我们都知道我们人类的年龄都是非负数,所以我们这里用unsigned int(无符号整数)类型。但是,目前人类科技水平有限,还没有研究出是否有外星人存在,就更无法确定其年龄属性了,所以我们这里假设外星人的年龄可以为负数(如果你反驳我你也没依据啊,暂且就这样吧),那么就定义其为int类型,如果我们要将外星人映射到人类上,其实就是uint到int之间的映射:
namespace FrontAutoMapper
{
class Program
{
static void Main(string[] args)
{
//创建映射,映射条件是源类型的Age属性在区间(0,149)范围内
Mapper.CreateMap<Aliens, Person>().ForMember(dest => dest.Age, opt => opt.Condition(src => src.Age > && src.Age < )); var p1 = Mapper.Map<Person>(new Aliens() { Age = - });//不符合映射条件
var p2 = Mapper.Map<Person>(new Aliens() { Age = });//不符合映射条件
var p3 = Mapper.Map<Person>(new Aliens() { Age = });//符合映射条件
var p4 = Mapper.Map<Person>(new Aliens() { Age = });//符合映射条件
var p5 = Mapper.Map<Person>(new Aliens() { Age = });//不符合映射条件
Console.WriteLine(p1.Age);//映射不成功,返回Person.Age默认值22
Console.WriteLine(p2.Age);//映射不成功,返回Person.Age默认值22
Console.WriteLine(p3.Age);//映射成功,返回新值1
Console.WriteLine(p4.Age);//映射成功,返回新值148
Console.WriteLine(p5.Age);//映射不成功,返回新值22
Console.Read();
}
}
public class Person
{
public Person()
{
Age = ;
}
public uint Age { set; get; }//Person的Age属性默认值是22
} public class Aliens
{
public Aliens()
{
Age = -;
}
public int Age { get; set; }//Aliens的Age属性默认值是-23
}
}
这个例子是将年龄Age在区间(0,149)范围内的外星人映射成人,执行结果如下,和预测结果一致。

配置
初始化
初始化是配置AutoMapper受人欢迎的模式,每个应用域应该配置一次:
//初始化配置文件
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Aliens, Person>();
cfg.AddProfile<AliensPersonProfile>();//添加一个配置文件
});
映射配置是静态的,此后不应该改变了。
Profile实例
可用来组织AutoMapper配置
namespace ConditionalMapping
{
public class AliensPersonProfile : Profile
{
protected override void Configure()
{
//放一些CreateMap(...)等映射配置操作 }
}
}
自定义一个继承了Profile类的类,然后重写Configure方法,在该方法中放一些映射的配置。
像下面这样初始化自定义的配置文件:
//初始化配置文件
Mapper.Initialize(cfg =>
{
cfg.AddProfile<AliensPersonProfile>();//添加一个配置文件
});
命名惯例
可以设置源和目标的命名惯例。
//初始化配置文件
Mapper.Initialize(cfg =>
{
cfg.SourceMemberNamingConvention=new LowerUnderscoreNamingConvention();
cfg.DestinationMemberNamingConvention=new PascalCaseNamingConvention();
});
也可以在配置文件中的Configure方法中设置:
protected override void Configure()
{
SourceMemberNamingConvention = new LowerUnderscoreNamingConvention();
DestinationMemberNamingConvention = new PascalCaseNamingConvention();
}
小试牛刀:
在Aliens类中添加如下代码:
public string MyName { set; get; }
在Person类中添加如下代码:
public string my_name { get; set; }
结果如下,和预测结果一致:

可见,这种映射配置就是告诉AutoMapper这两种命名惯例可以相互映射。而且需要注意的是,这两句代码可放在CreateMap()方法之后。
替换字符
在成员名字映射期间,也可以替换个别的字符或者整个单词。
配置Mapper(可在Initialize方法或配置文件中均可,后面不再提示),注意一定要在CreateMap方法之前,配置替换字符,否则没有效果。这也符合逻辑,只有先添加替换条件,才能按条件映射嘛。
cfg.ReplaceMemberName("Ä", "A");
cfg.ReplaceMemberName("í", "i");
cfg.ReplaceMemberName("Tool", "Car");
cfg.AddProfile<AliensPersonProfile>();
小试牛刀:
在Aliens类中添加如下代码:
public int Ävíator { get; set; }
public string ToolName { get; set; }
在Person类中添加如下代码:
public int Aviator { get; set; }
public string CarName { get; set; }
结果如下,和预测结果一致:

识别前缀/后缀
有时候你的源类型和目标类型的属性有公共的前缀/后缀,由于这些命名不匹配的缘故,使你不得不处理这些自定义的成员映射。为了实现这个,可以识别前后缀:
小试牛刀:
在Aliens类中添加如下代码:
public string PGender { get; set; }
在Person类中添加如下代码:
public string Gender { get; set; }
可见,源类型中有一个前缀为“P”的字段PGender,要想成功映射为Person,就必须识别出前缀“P”,所以在Mapper的配置中添加代码(注意,添加到CreateMap方法之前,否则无效):
cfg.RecognizePrefixes("P");
结果如下,和预测结果一致:

默认情况下,AutoMapper识别前缀“Get”,如果你需要清除前缀:
cfg.ClearPrefixes();
全局属性/字段过滤
默认情况下,AutoMapper映射每一个公共的属性/字段。你可以使用属性/字段过滤器过滤出不需要映射的属性/字段:
//不映射任何字段
cfg.ShouldMapField = fi => false;
//只映射getter是private的属性
cfg.ShouldMapProperty = pi => pi.GetMethod != null && pi.GetMethod.IsPrivate;
cfg.AddProfile<AliensPersonProfile>();
小试牛刀:
分别给Aliens和Person类添加下面这段代码:
private string code;
public string Code
{
private get { return code; }
set { code = value; }
}
Main方法中添加代码:
var p10 = Mapper.Map<Person>(new Aliens() { Age = ,Code = ""});
Console.WriteLine(string.Format("Person.Age={0},Person.code={1}",p10.Age,p10.code));//22,111
结果和预测一样:

解释一下:
我们在配置中添加了过滤器,只允许getter是private的属性映射,而Person的Age属性getter默认是public的,所以没有将我们给的值44映射到,因而返回默认的22,而Person的Code属性的getter是私有的,所以映射到了,但是要想取到映射后的值,我们只能通过公有的字段来获得。
配置可见性
默认情况下,AutoMapper只识别公有成员。虽然可以映射到私有的setter,但是如果整个属性是private/internal的,那么就会跳过internal/private的方法和属性。为了命令AutoMapper识别具有其他可见性的成员,重写默认的过滤器ShouldMapField或ShouldMapProperty:
Mapper.Initialize(cfg =>
{
// 映射具有public或internal的getter的属性
cfg.ShouldMapProperty = p => p.GetMethod.IsPublic || p.GetMethod.IsAssembly;
cfg.CreateMap<Source, Destination>();
});
AutoMapper(一)的更多相关文章
- 恋爱虽易,相处不易:当EntityFramework爱上AutoMapper
剧情开始 为何相爱? 相处的问题? 女人的伟大? 剧情收尾? 有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易 ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- AutoMapper
什么是AutoMapper? AutoMapper是一个对象和对象间的映射器.对象与对象的映射是通过转变一种类型的输入对象为一种不同类型的输出对象工作的.让AutoMapper有意思的地方在于它提供了 ...
- AutoMapper随笔记
平台之大势何人能挡? 带着你的Net飞奔吧! http://www.cnblogs.com/dunitian/p/4822808.html#skill 先看效果:(完整Demo:https://git ...
- AutoMapper:Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html 应用场景:ViewModel==>Mode映射的时候出错 AutoMappe ...
- AutoMapper的介绍与使用(一)
软件环境 vs2015 asp.net mvc 5 .NET Framework 4.5.2 AutoMapper 5.2.0.0 AutoMapper安装 新建asp.net mvc 项目 Auto ...
- AutoMapper使用中的问题
指定值只会执行一次 public class MomanBaseProfile : Profile { public MomanBaseProfile() { CreateMap<Request ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(中)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(下)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 【道德经】漫谈实体、对象、DTO及AutoMapper的使用
写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...
随机推荐
- 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少
开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...
- 踩石行动:ViewPager无限轮播的坑
2016-6-19 前言 View轮播效果在app中很常见,一想到左右滑动的效果就很容易想到使用ViewPager来实现.对于像我们常说的banner这样的效果,具备无限滑动的功能是可以用ViewPa ...
- .NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布
众所周知,Red Hat和微软正在努力使.NET Core成为Red Hat企业版Linux (RHEL)系统上的一流开发平台选项.这个团队已经一起工作好几个月了,RHEL对.NET有许多需求.今天在 ...
- Linux虚拟机的安装(使用Centos6.3)
1.什么是虚拟机? 虚拟机指通过软件模拟的具有完整硬件系统功能的.运行在一个完全隔离环境中的完整计算机系统 2.安装Linux虚拟机前要做的准备 2.1:一台windows环境的pc 2.2:下载VM ...
- excel 日期/数字格式不生效需要但双击才会生效的解决办法
原因: Excel2007设置过单元格格式后,并不能立即生效必须挨个双击单元格,才能生效.数据行很多.效率太低. 原因:主要是一些从网上拷贝过来的日期或数字excel默认为文本格式或特殊-中文数字格式 ...
- 参考bootstrap中的popover.js的css画消息弹框
前段时间小颖的大学同学给小颖发了一张截图,图片类似下面这张图: 小颖当时大概的给她说了下,其实小颖也不知道上面那个三角形怎么画嘻嘻,给她说了DOM结构,具体的css让她自己百度,今天小颖自己参考boo ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
- TFS 测试用例步骤数据统计
TFS系统集成了一套BI系统,基于SQL Server的Analysis Service进行实现的.通过这几年的深入使用,能够感触到这个数据数据仓库模型是多么的优秀,和微软官方提供的数据仓库示例Adv ...
- Redis简单案例(二) 网站最近的访问用户
我们有时会在网站中看到最后的访问用户.最近的活跃用户等等诸如此类的一些信息.本文就以最后的访问用户为例, 用Redis来实现这个小功能.在这之前,我们可以先简单了解一下在oracle.sqlserve ...
- 海康网络摄像机YV12转换为BGR,由opencv Mat显示 (转)
我使用的是海康DS-2CD852MF-E, 200万,网络摄像机,已经比较老了,不过SDK在海康官网下载的,开发流程都差不多. 海康摄像机回调解码后的视频数据格式为YV12,顺便说一下YV12的数据格 ...