AutoMapper搬运工之自定义映射

回顾

上节说到了AutoMapper的简单使用,对于复杂的Mapping需要强大的自定义,这节我们来看下AutoMapper的自定义Mapping(Projection)

搬运自Git:https://github.com/AutoMapper/AutoMapper/wiki/Projection

实例

本篇的场景是一个简单的日历事件,我们首先定义一个日历的事件如下:

1 public class CalendarEvent
2 {
3     //事件日期
4     public DateTime Date { get; set; }
5     //事件标题
6     public string Title { get; set; }
7 }

那么在页面,我们需要显示这个事件的具体信息,而且是可编辑的,定义一个ViewModel dto如下:

 1 public class CalendarEventForm
 2 {
 3     //事件日期
 4     public DateTime EventDate { get; set; }
 5     //时间对应的小时
 6     public int EventHour { get; set; }
 7     //时间对应的分钟
 8     public int EventMinute { get; set; }
 9     //事件标题
10     public string Title { get; set; }
11 }

也许你会小小的纠结下,为啥要这么定义,页面上js直接转换之类的,好吧,这就是一个例子,你明白就好。

接下来和本系列一贯的做法一样,我们来看下手写Mapping的方式:

 1 // 定义一个日历事件
 2 var calendarEvent = new CalendarEvent
 3 {
 4     Date = new DateTime(2014, 12, 15, 20, 30, 0),
 5     Title = "公司聚会"
 6 };
 7
 8 CalendarEventForm form = new CalendarEventForm
 9 {
10     EventDate = calendarEvent.Date.Date,
11     EventHour =  calendarEvent.Date.Hour,
12     EventMinute = calendarEvent.Date.Minute,
13     Title = calendarEvent.Title
14 };

这个Mapping依然很简单,没什么疑问,咱们来对比下使用AutoMapper:

1 // 配置Mapping
2 Mapper.CreateMap<CalendarEvent, CalendarEventForm>()
3         .ForMember(dest => dest.EventDate, opt => opt.MapFrom(src => src.Date.Date))
4         .ForMember(dest => dest.EventHour, opt => opt.MapFrom(src => src.Date.Hour))
5         .ForMember(dest => dest.EventMinute, opt => opt.MapFrom(src => src.Date.Minute));
6
7 //Mapping
8 CalendarEventForm form = Mapper.Map<CalendarEvent, CalendarEventForm>(calendarEvent);

有什么感想?是不是感觉代码高大上,但是跟手写的没啥区别,哈哈,别着急,这只是一个例子。对于复杂的场景,你自然会体会到AutoMapper使代码简洁,配置统一。

说道配置这里需要说明一下:Mapping的配置并不是这样每次都要Create的,具体的说明,请期待下篇 《AutoMapper之配置》

回到上面的代码,我们来进一步的说明下这个ForMember

ForMember函数

AutoMapper提供了相关的API来支持自定义的Mapping配置,并且他支持lamda哦。

看一下ForMember的定义:

1 IMappingExpression<TSource, TDestination> ForMember(Expression<Func<TDestination, object>> destinationMember

第一个参数是目标属性,第二个参数是一定义的映射Expression, Expression让这个映射变得更加的动态,可以直接使用表达式或者干脆直接来个函数调用:

 1 .ForMember(dest => dest.Title, opt => opt.MapFrom(src => ChangeTitle(src.Title));//调用方法
 2 .ForMember(dest => dest.Title, opt => opt.MapForm(src => src.Title.Where(....);//表达式
 3
 4 void ChangeTitle(string title)
 5 {
 6     //自定义处理
 7     ...
 8
 9     return "myName" + title;
10 }

有关Expression的内容及构造请参考表达式的文章,这里边的水很深,有机会我也去深入研究分享些内容。

细心的你或许会发现,如果映射写了多个会怎么样?经过测试,结论是:只有第一个配置是有效的,之后的同参数映射AutoMapper会自动忽略。

另外,还有一个ForMembers函数不过并不是很常用,其他的函数请自行研究,如果我有研究使用后面的系列我会一一分享。本节仍然是简单的内容,如果大家有更好的建议请留言,我觉得可能搬运的太简单,没有给人具体的映象的感觉。

时间: 2024-08-26 09:52:13

AutoMapper搬运工之自定义映射的相关文章

AutoMapper搬运工之自定义类型转换

前言 最近还挺忙,还有点累,一直都没更新了,实在是懒呀.正题之前先说点别的,最近公司要扩张了,需要大量开发,领导说推荐有钱可以拿,如此好机会,我就趁机做个广告.ShippingRen.com招募.NET高级开发,坐标上海,有兴趣的给我留言,或者加我qq:1029183866,加的时候请说明博客园看到. 另外在说说这几天,工作忙是不可避免,业余也在准备自己的网站www.capqueen.com(目前还在备案中),准备用目前会的技术从无到有建立一个CMS(博客),到时候也会发一些文章和大家分享.最近

AutoMapper搬运工之配置

回顾 前几篇搬运了AutoMapper的基本用法,自定义映射,相信有看的同学已经会使用AutoMapper这个强大的Mapping工具了.不过细心的你是否还记得前几篇中有提到Map的创建并非是每次都需要Create,那么AutoMapper对于这些如果管理呢?这篇我们就要来看看AutoMapper的配置. 初始化 AutoMapper提供一个初始化函数(Mapper.Initialize),可以在程序初始化时调用(Web应用程序可以在Global.asax里写),进行统一的配置初始化.前几个章节

AutoMapper搬运工之初探AutoMapper

写在前面 知道AutoMapper很久了,但是一直没有用,最近刚好有个场景需要就用了,果然是利器.看了git上的wiki,发现内容其实wiki上写的很全面了,深入的暂时还没挖掘到.不过和群里的朋友交流了下,觉得充当下搬运工,小小的翻译下还是挺好的,小弟不才,希望看客大牛们轻拍砖. 什么是AutoMapper? AutoMapper是一个完善的Mapping工具,所谓Mapping即数据对象转换,借用群里朋友的话是多用于领域对象和DTO对象的Mapping或者是SqlDataReader的Mapp

AutoMapper指定列名进行映射

有了AutoMapper,就再也不用进行手工一对一的从IDataReader到实体字段的赋值.这篇博文是一个实际案例的记录. 实体类型定义如下: public class UploadImage { public int Id { get; set; } public string Src { get; set; } } Src属性在数据库中对应的字段名为ImageUrl. 映射要求:从IDataReader到IEnumerable<UploadImage>,代码如下: using (var

学习windows编程 day4 之 自定义映射

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; int iMapMode; static int cxClient, cyClient; switch (message) { case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam);

AutoMapper多个源映射到一个Dto

AutoMapper多个源映射到一个Dto 首先要引入AutoMapper(我电脑用的8.0,9.0版本) 1. 定义源映射对象 Model如下: 实体Social /// <summary> /// 社会属性 /// </summary> public class Social { public int Age { get; set; } public bool IsMarried { get; set; } public string Name { get; set; } }

.Net Core使用AutoMapper做对象关系映射

我想很多后端开发者,纠结于如何在Dto及表实体中做属性关系映射,因为真的太繁琐了., ⒈如何使用? 1 Mapper.Initialize(cfg => cfg.CreateMap<UsersInputDto, Users>()); 2 UsersInputDto input = new UsersInputDto() 3 { 4 id = 1, firstname = "fan", lastname = "qi", uname = "f

AutoMapper 创建嵌套对象映射(原创)

之前在做DTO转换时,用到AutoMapper.但DTO的层次太深了,无奈官方没针对嵌套类型提供好的解决方案,于是自己实现了一下: 思路:采用递归和反射很好的避免手工创建嵌套对象的映射. 第一个版本,已经提交到:https://github.com/AutoMapper/AutoMapper/wiki/Nested-mappings 1 /// <summary> 2 /// 递归创建类型间的映射关系 (Recursively create mappings between types) 3

遭遇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