1. 首页
  2. 文章列表
  3. AutoMapper6.x起步

写在前面

这段时间写自己的博客系统,遇到的问题还是不少的,其中有部分就是要通过EntityFramework调用存储过程,而EF生成的存储过程会单独地生成一个存储过程的实体类,要从这个存储过程的实体类转换到普通的实体类这就麻烦了,得不停地去反射操作,当然有些时候还得在视图模型和实体之间转换(OOM),这都只有通过反射来操作,太麻烦!要是实体中有集合属性或者导航属性,那就更麻烦了!AutoMapper就自动帮我们解决了这样的问题,所以,将自己的学习成果记在这里,方便自己以后忘记时再次查阅,也方便初学者起步:

OOM顾名思义,Object-Object-Mapping实体间相互转换,AutoMapper也是个老生常谈了,其意义在于帮助你无需手动的转换简单而又麻烦的实体间关系,比如ViewModel和entity的转换,SearchModel和Entity的转换,关于automapper的使用,网上大多数的分享都是几年前的,很多方法已经被废弃,到了编译器里会告诉你该方法已经过时,废弃的,不建议使用的,比如Mapper.CreateMap等方法,当然老司机大多数直接就去github看文档了,或者google一下就了解了,但是中文资料关于方法废弃后,并没有什么说明了,对于小白那就可能就痛苦了。本篇的五个实例可以帮你解决常见的基本问题.

预备

首先我们预备一些DTO和TModel。DTO就是你和用户交互的实体,专业解释为数据传输对象(Data Transfer Object),你也可以理解为视图模型(ViewModel)。TModel就是你与数据库打交道的实体。

实体展示如下:

TModel有如下三个简单的实体,他们有独立的实体,也有一对多的实体。

public class Address
{
    public string Country { get; set; }
    public string City { get; set; }
    public string Street { get; set; }
    public string PostCode { get; set; }
    public string CreateTime { get; set; }
    public int CreateUserId { get; set; }
}
public class Author
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Contact> Contact { get; set; }
}
public class Contact
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string Blog { get; set; }
    public string Twitter { get; set; }
}

DTO对象有如下三个:

public class AddressDto
{
    public string Country { get; set; }
    public string City { get; set; }
    public string City2 { get; set; }
}
public class AuthorDto
{
    public string Name { get; set; }
    public string Description { get; set; }
    public List<ContactDto> Contact { get; set; }
}
public class ContactDto
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string Blog { get; set; }
    public string Twitter { get; set; }
}

起步:单个实体转换

单个实体转换的时候,在属性字段名称完全匹配的情况下,你只需指定两个实体间的转换规则,指定source源实体和destination目标实体。那么你应该参照如下实例:

var dto= new AddressDto
{
    Country = "China",
    City = "Beijing"
};
Mapper.Initialize(m => m.CreateMap<AddressDto, Address>());
Address address = Mapper.Map<AddressDto, Address>(dto);

请注意在AutoMapper5.x当中,Initialize来初始化你的规则是首选的。

在你指定转换规则后,请使用Map方法,进行转换并输出你的目标实体。还有第一个参数代表SourceModel,第二个参数是DestinationModel.

单个实体不同名属性转换

当你需要对不同名称的字段来进行映射的时候,请注意使用ForMember方法,第一个参数需要你制定所需特殊配置的目标字段,第二个参数你则需要制定你对该字段属性的操作,我选择了它提供的MapFrom方法,意义在于告诉AutoMapper,我需要讲目标实体的City来源 指定为 源实体的City2属性值。

var dto = new AddressDto
{
    Country = "China",
    City2 = "Beijing"
};
Mapper.Initialize(m => m.CreateMap<AddressDto, Address>().ForMember(x => x.City, opt => opt.MapFrom(o => o.City2)));
Address address = Mapper.Map<AddressDto, Address>(dto);

集合转换

在集合间转换的时候,你不需要配置目标List与源List对象中的匹配,而只需要配置你泛型对象的映射匹配关系。

var address = new Address { Country = "China", City = "Beijing" };
var address2 = new Address() { Country = "USA", City = "New York" };
var addressList = new List<Address>() { address2, address };
Mapper.Initialize(m => m.CreateMap<Address, AddressDto>());//这里仅需配置实体间的转换,而不是实体集合的转换
List<AddressDto> res = Mapper.Map<List<Address>, List<AddressDto>>(addressList);

实体包含不同类型属性转换(忽略属性)

在实体包含不同类型属性的时候,比如TModel1中包含了一个List<TModel>,而你的Dto1中包含了一个List<Dto>.这个时候你可以选择忽略这个属性


var contacts = new List<Contact>() { new Contact(){ Blog = "myblog", Email = "456@qq.com" }, new Contact() { Blog = "myblog", Email = "l23@qq.com" } };
var author = new Author() { Description = "描述", Name = "李四", Contact = contacts };
Mapper.Initialize(m => { m.CreateMap<Author, AuthorDto>().ForMember(x => x.Contact, opt => opt.Ignore()); });
AuthorDto Dto = Mapper.Map<Author, AuthorDto>(author);
//这里的Ignore代表配置Contract该属性的操作  为忽略Ignore,映射时将忽略该属性,由于List<Contact>()和List<ContactDto>() 是不同类型,所以需要配置忽略或者是特殊映射,特殊映射例子看下方

实体包含不同类型属性转换(指定属性Mapfrom)

当然你需要这个属性的时候,你可以不忽略他,而是使用MapFrom来进行特殊的指定,并且在类型不相同的时候,你要指定你两个类型间的映射匹配关系。正如下面实例中的m.CreateMap<Contact, ContactDto>(); 和 m.CreateMap<Author, AuthorDto>().ForMember(x => x.Contact, opt => opt.MapFrom(o => o.Contact));

var contacts = new List<Contact>()
{
    new Contact() {Blog = "myblog", Email = "123@qq.com"},
    new Contact() {Blog = "myblog", Email = "456@qq.com"}
};
var author = new Author() {Description = "描述", Name = "张三", Contact = contacts};
Mapper.Initialize(m =>
{
    m.CreateMap<Contact, ContactDto>(); //注意内部不同类型实体转换时必要的
    m.CreateMap<Author, AuthorDto>().ForMember(x => x.Contact, opt => opt.MapFrom(o => o.Contact)); //注意制定MapFrom是必要的
});


下载为Word文档

版权声明:

本文仅用于学习、研究和交流目的,欢迎非商业性质转载。本文链接:http://masuit.com/156

l  博主在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系。挖井挑水无水表,不会网购无快递。

l  文章内容部分来源于互联网,不代表本人的任何立场;涉及到的软件来源于互联网,仅供个人下载使用,版权归该软件开发者所有,请勿用于商业用途,下载后请于24小时内删除,请支持正版!因下载本站资源造成的损失,全部责任由使用者本人承担!如果你是原作者,认为本文内容对您的权益有所侵犯,请联系博主进行投诉,待博主进行严格地审查和背景调查后,情况属实的将在三天内将本文删除或修正。

l  博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高(其实是个菜B),不足和错误之处在所难免,希望大家能够批评指出。

l  博主是利用读书、参考、引用、抄袭、复制和粘贴等多种方式打造成自己的纯镀 24k 文章,请原谅博主成为一个无耻的文档搬运工!

l  博主只是一名普通的互联网从业者,不懂修电脑,不会卖电脑,不会帮你盗号,不会破解开机密码,找不回你丢失的手机等,如有这样的想法请绕道!

相关推荐:

浅谈MVC的Attribute路由,教你一步一步设计出漂亮的路由 谈一谈单例模式、静态类和线程内唯一对象有什么区别
经典面试题之——如何自由转换两个没有继承关系的字段及类型相同的实体模型 浅谈EF中LINQ查询原理
C# vs Java:C# 五个不可替代的特性瞬间秒杀 Java C#经典面试题——深入理解IEnumerable和IQueryable两接口的区别
.NET Office组件神器——Aspose.Total 17.x破解版+破解补丁下载 深入理解C#中的IDisposable接口
深入浅出依赖注入容器——Autofac 五分钟重温C#委托,匿名方法,Lambda,泛型委托,表达式树

评论区:

    还没有评论哦,赶紧来写评论吧

    分享按钮