一、AutoMapper初探

[参考Using AutoMapper: Getting Started]

1.新建空的ASP.NET MVC项目

2.在Models文件夹添加类

    public class Book
{
public string Title { get; set; }
}
    public class BookViewModel
{
public string Title { get; set; }
}

3.安装AtuoMapper

Install-Package AutoMapper

4.在App_Start文件夹添加配置类

    public static class AutoMapperConfig
{
public static void RegisterMappings()
{
AutoMapper.Mapper.CreateMap<Book, BookViewModel>();
}
}

5.在Global.asax中注册

AutoMapperConfig.RegisterMappings();

6.新建HomeController

        public string Index()
{
var book = new Book{Title="水浒传" };
var bookModel = AutoMapper.Mapper.Map<Book>(book);
return bookModel.Title;
}

7.运行程序

  aaarticlea/png;base64,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" alt="" />

二、创建映射

[参考Using AutoMapper: Creating Mappings]

1.CreateMap方法

  AutoMapper所有映射都是使用CreateMap方法定义的:

AutoMapper.Mapper.CreateMap<SourceClass, DestinationClass>();

  需要注意的是,上面定义的映射是单向映射。例如,我们定义了如下映射:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>();

  我们可以将一个Book实例映射到一个BookViewModel实例:

var bookViewModel = AutoMapper.Mapper.Map<BookViewModel>(book);

  但是我们不能将一个BookViewModel实例映射到一个Book实例:

var book = AutoMapper.Mapper.Map<Book>(bookViewModel);

  如果要实现双向映射,需要再次调用CreateMap方法定义:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>();
AutoMapper.Mapper.CreateMap<BookViewModel, Book>();

  如果我们不需要为反向映射定义任何自定义映射逻辑,我们可以使用ReverseMap实现双向映射:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>().ReverseMap();

2.映射规则

  AutoMapper有一些映射约定,其中一个约定就是同名映射。例如:

public class Book
{
public string Title { get; set; }
} public class NiceBookViewModel
{
public string Title { get; set; }
} public class BadBookViewModel
{
public string BookTitle { get; set; }
}

  如果我们将一个Book实例映射到一个NiceBookViewModel实例,Title属性的值会是我们所期望的值。然而如果我们将一个Book实例映射到一个BadBookViewModel实例,Title属性的值会为null。因为名字不同,AutoMapper无从知晓BookTitle需要从Title获取值。这种情况下就需要我们手动添加配置代码:

AutoMapper.Mapper.CreateMap<Book, BadBookViewModel>()
.ForMember(dest => dest.BookTitle,
opts => opts.MapFrom(src => src.Title));

  另一个约定涉及到嵌入对象。例如:

public class Author
{
public string Name { get; set; }
} public class Book
{
public string Title { get; set; }
public Author Author { get; set; }
} public class BookViewModel
{
public string Title { get; set; }
public string Author { get; set; }
}

  尽管Book和BookViewModel都有Author属性,但是它们的类型不匹配,因此AutoMapper不能将Book.Author映射到BookViewModel.Author。对于嵌入对象,AutoMapper的约定是目标类属性的命名为骆驼拼写法的“对象名+对象属性名”。示例如下:

public class BookViewModel
{
public string Title { get; set; }
public string AuthorName { get; set; }
}

  如果不采用约定,我们依然可以使用配置代码:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>()
.ForMember(dest => dest.Author,
opts => opts.MapFrom(src => src.Author.Name));

3.投影

  在之前的示例中,如果我们把Author类修改为:

public class Author
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

  我们需要将这两个属性映射到一个属性,代码如下:

AutoMapper.Mapper.CreateMap<Book, BookViewModel>()
.ForMember(dest => dest.Author,
opts => opts.MapFrom(
src => string.Format("{0} {1}",
src.Author.FirstName,
src.Author.LastName)));

4.更复杂的投影

public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
} public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
} public class PersonDTO
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
}

  如果我们要把PersonDTO映射到Person,代码如下:

AutoMapper.Mapper.CreateMap<PersonDTO, Person>()
.ForMember(dest => dest.Address,
opts => opts.MapFrom(
src => new Address
{
Street = src.Street,
City = src.City,
State = src.State,
ZipCode = src.ZipCode
}));

5.嵌套映射

  上面的示例中,如果PersonDTO修改为:

public class AddressDTO
{
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
} public class PersonDTO
{
public string FirstName { get; set; }
public string LastName { get; set; }
public AddressDTO Address { get; set; }
}

  映射应该修改为:

AutoMapper.Mapper.CreateMap<PersonDTO, Person>();
AutoMapper.Mapper.CreateMap<AddressDTO, Address>();

三、映射到实例

[参考Using AutoMapper: Mapping Instances]

1.映射到新的实例

  之前的示例均产生一个新的实例,例如:

var destinationObject = AutoMapper.Mapper.Map<DestinatationClass>(sourceObject);

2.映射到已经存在的实例

AutoMapper.Mapper.Map(sourceObject, destinationObject);

3.映射到集合

var destinationList = AutoMapper.Mapper.Map<List<DestinationClass>>(sourceList);

  我们可以映射到所有的集合类型和接口:List<T>、ICollection<T>、IEnumerable<T>等。

  但是如果我们尝试映射到现有的实例:

AutoMapper.Mapper.Map(sourceList, destinationList);

  我们会发现destinationList已经被损坏。因为AutoMapper实际上是映射到集合而不是分别映射到集合中的对象。当我们考虑对象的层级结构时,这种情况就变得十分讨厌。例如:

public class Pet
{
public string Name { get; set; }
public string Breed { get; set; }
} public class Person
{
public List<Pet> Pets { get; set; }
} public class PetDTO
{
public string Name { get; set; }
public string Breed { get; set; }
} public class PersonDTO
{
public List<PetDTO> Pets { get; set; }
}

  如果我们创建一个只更新Name属性的表单,我们提交的对象图会是这样:

{
Pets: [
{ Name : "Sparky", Breed : null },
{ Name : "Felix", Breed : null },
{ Name : "Cujo", Breed : null }
]
}

  由于Breed属性没有被传递,它在每个PetDTO中的值为null。现在如果我们使用PersonDTO更新Person:

AutoMapper.Mapper.Map(person, personDTO);

  这样Person中每个Pet的Breed属性均变为null。这种问题解决起来有点麻烦,首先我们需要使用Ignore方法:

AutoMapper.Mapper.CreateMap<PersonDTO, Person>()
.ForMember(dest => dest.Pets,
opts => opts.Ignore());

  上面的代码告诉AutoMapper不映射Pets集合,这就意味着我们现在必须手动处理:

AutoMapper.Mapper.Map(person, personDTO);
for (int i = ; i < person.Pets.Count(); i++)
{
AutoMapper.Mapper.Map(person.Pets[i], personDTO.Pets[i]);
}

  上面的代码是基于假设两个list是相同的即我们没有对它们重新排序,并且不允许在表单添加或者删除项。为了解决重新排序后不一致的问题,我们需要依赖某些标识属性。例如:

var pet = person.Pets[i];
var updatedPet = personDTO.Pets.Single(m => m.Id == pet.Id);
AutoMapper.Mapper.Map(pet, updatedPet);

  添加或者删除项会更复杂一些:

var updatedPets = new List<Pet>();
foreach (var pet in personDTO.Pets)
{
var existingPet = person.Pets.SingleOrDefault(m => m.Id == pet.Id);
// No existing pet with this id, so add a new one
if (existingPet == null)
{
updatedPets.Add(AutoMapper.Mapper.Map<Pet>(pet));
}
// Existing pet found, so map to existing instance
else
{
AutoMapper.Mapper.Map(existingPet, pet);
updatedPets.Add(existingPet);
}
}
// Set pets to updated list (any removed items drop out naturally)
person.Pets = updatedPets;

  这可能是使用AutoMapper最大的难点,但是只要我们在执行更新操作的时候记得手动映射list项就行了。

使用AutoMapper的更多相关文章

  1. 恋爱虽易,相处不易:当EntityFramework爱上AutoMapper

    剧情开始 为何相爱? 相处的问题? 女人的伟大? 剧情收尾? 有时候相识即是一种缘分,相爱也不需要太多的理由,一个眼神足矣,当EntityFramework遇上AutoMapper,就是如此,恋爱虽易 ...

  2. 【AutoMapper官方文档】DTO与Domin Model相互转换(上)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  3. AutoMapper

    什么是AutoMapper? AutoMapper是一个对象和对象间的映射器.对象与对象的映射是通过转变一种类型的输入对象为一种不同类型的输出对象工作的.让AutoMapper有意思的地方在于它提供了 ...

  4. AutoMapper随笔记

    平台之大势何人能挡? 带着你的Net飞奔吧! http://www.cnblogs.com/dunitian/p/4822808.html#skill 先看效果:(完整Demo:https://git ...

  5. 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 ...

  6. AutoMapper的介绍与使用(一)

    软件环境 vs2015 asp.net mvc 5 .NET Framework 4.5.2 AutoMapper 5.2.0.0 AutoMapper安装 新建asp.net mvc 项目 Auto ...

  7. AutoMapper使用中的问题

    指定值只会执行一次 public class MomanBaseProfile : Profile { public MomanBaseProfile() { CreateMap<Request ...

  8. 【AutoMapper官方文档】DTO与Domin Model相互转换(中)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  9. 【AutoMapper官方文档】DTO与Domin Model相互转换(下)

    写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...

  10. 【道德经】漫谈实体、对象、DTO及AutoMapper的使用

    写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...

随机推荐

  1. Spring + iBatis 的多库横向切分简易解决思路

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  2. 基于Android 平台简易即时通讯的研究与设计[转]

    摘要:论文简单介绍Android 平台的特性,主要阐述了基于Android 平台简易即时通讯(IM)的作用和功能以及实现方法.(复杂的通讯如引入视频音频等可以考虑AnyChat SDK~)关键词:An ...

  3. .NET实现单点登录研究过程总结--【SSO】

    一.单点登录实现结果: 权限系统登录后,新生系统通过拦截器,获取本地的cookie能够訪问该系统:权限系统用户注销后,销毁本地cookie.訪问新生链接.自己主动跳转到登录首页. 二.主要遇到的问题: ...

  4. ABAP 日期函数

    一 财务期间处理 T_CODE: OB29 **取 公司年度变式, 和 货币  SELECT SINGLE waers periv FROM t001        INTO (v_waers,v_p ...

  5. Python 将文本转换成html的简单示例

    实例txt文件test_input.txt: Welcome to World Wide Spam. Inc. These are the corporate web pages of *World ...

  6. Linq的小知识(一),大家可以学习一下

    linq的简介 lLINQ是Language Integrated Query的简称,它是集成在.NET编程语言中的一种特性.已成为编程语言的一个组成部分,在编写程序时可以得到很好的编译时语法检查,丰 ...

  7. 23、从头学Android之ContentProvider .

    http://blog.csdn.net/jiahui524/article/details/7016430 应用场景: 在Android官方指出的Android的数据存储方式总共有五种,分别是:Sh ...

  8. 使用 Eclipse 的 Navigator Link Helper 实现导航器与编辑器的关联

    概要 Link With Editor 是 Eclipse 内置功能中十分小巧,但却异常实用的一个功能.这个开关按钮 (Toggle Button) 出现在各式导航器视图 ( 例如 Resource ...

  9. 定位CoreLocation

    一.定位 iOS三种定位方式: CoreLocation 按定位的准确性: GPS(Global Positioning System全球定位系统); 蜂窝式基站; wifi; 定位顺序:1. 首选G ...

  10. js解析XML

    //在当前页面内追加换行标签和指定的HTML内容function w( html ){    $(document.body).append("<br/>" + htm ...