AutoMapper(六)
返回总目录
List和数组
AutoMapper只要求元素类型的配置而不要求可能会用到的任何数组或者list类型。比如,我们有一个简单的源和目标类型:
public class Source
{
public int Value { get; set; }
} public class Destination
{
public int Value { get; set; }
}
支持所有的基本泛型集合,代码如下:
class Program
{
static void Main(string[] args)
{
Mapper.CreateMap<Source, Destination>();
var sources = new[]
{
new Source() {Value = 1},
new Source() {Value = 2},
new Source() {Value = 3},
};
IEnumerable<Destination> iEnumerableDests= Mapper.Map<IEnumerable<Destination>>(sources);
ICollection<Destination> iCollectionDests= Mapper.Map<ICollection<Destination>>(sources);
IList<Destination> iListDests= Mapper.Map<IList<Destination>>(sources);
List<Destination> listDests= Mapper.Map<List<Destination>>(sources);
Destination[] destsArr= Mapper.Map<Destination[]>(sources);
//这里只举两个例子,其他集合同理
foreach (var dest in iCollectionDests)
{
Console.Write(dest.Value+",");
}
Console.WriteLine();
foreach (var dest in destsArr)
{
Console.Write(dest.Value + ",");
}Console.Read();
}
}
以上代码是集合和集合之间的映射,但是映射的配置CreateMap方法中只是配置的是类型之间的映射,而没有设计任何集合类型。
测试结果如下,可见集合之间映射成功:

具体来说,支持的源集合类型包括:
- IEnumerable
- IEnumerable<T>
- ICollection
- ICollection<T>
- IList
- IList<T>
- List<T>
- Arrays
集合中的多态元素类型
很多时候,在我们的源和目标类型中可能有一个类型层次关系。AutoMapper支持多态数组和集合,因此如果发现派生的源或者目标类型,就会使用它们。
public class ParentSource
{
public int Value1 { get; set; }
} public class ChildSource : ParentSource
{
public int Value2 { get; set; }
} public class ParentDestination
{
public int Value1 { get; set; }
} public class ChildDestination : ParentDestination
{
public int Value2 { get; set; }
}
AutoMapper仍然要求显示配置孩子映射,因为它不能“猜出”具体使用哪一个孩子目标映射。
在Main方法中添加如下代码:
Mapper.Initialize(c =>
{
c.CreateMap<ParentSource, ParentDestination>()
.Include<ChildSource, ChildDestination>();
c.CreateMap<ChildSource, ChildDestination>();
});
var sources = new[]
{
new ParentSource(){Value1 = 11},
new ChildSource(){Value2 = 22},
new ParentSource(),
}; var dests = Mapper.Map<ParentDestination[]>(sources);
Console.WriteLine(dests[0]);
Console.WriteLine(dests[1]);
Console.WriteLine(dests[2]);
测试结果如下:

上面我们创建了一个源的数组,其中包含两个ParentSource和一个ChildSource,所以两个ParentSource成功地映射到了ParentDestination,而CreateMap配置中,ParentSource到ParentDestination的映射配置包含了ChildSource到ChildDestination的配置,所以执行Mapper.Map<ParentDestination[]>(sources)的时候,也可以将ChildSource映射到ChildDestination。
映射继承
在派生类中标明继承
上面的代码,是在基类中配置继承的,除此之外,也可以在派生类中配置继承:
//在基类中配置继承
Mapper.Initialize(c =>
{
c.CreateMap<ParentSource, ParentDestination>()
.Include<ChildSource, ChildDestination>();
c.CreateMap<ChildSource, ChildDestination>();
});
//在派生类中配置继承
Mapper.Initialize(c =>
{
c.CreateMap<ParentSource, ParentDestination>();
c.CreateMap<ChildSource, ChildDestination>()
.IncludeBase<ParentSource, ParentDestination>();
});
继承映射属性
这里介绍一下额外的复杂性,因为一个属性映射时可以有多种方式。下面是这些源的优先级:
- 显式映射 (使用.MapFrom())
- 继承的显式映射
- 惯例映射 (通过惯例匹配的属性)
- 忽略的属性映射
下面来演示一下:
这里还是用上面定义的四个类:Order,OrderDto,PCOrder,MobileOrder:
//领域对象
public class Order { }
//电脑端订单
public class PCOrder : Order
{
public string Referrer { get; set; }
}
//手机订单
public class MobileOrder : Order { } //Dtos
public class OrderDto
{
public string Referrer { get; set; }
}
配置映射的方法使用的是在父类中配置继承映射
//在父类中配置继承映射
Mapper.CreateMap<Order, OrderDto>()
.Include<PCOrder,OrderDto>()
.Include<MobileOrder,OrderDto>()
.ForMember(o => o.Referrer, m => m.Ignore());//这里配置了忽略目标属性Referrer的映射
Mapper.CreateMap<PCOrder,OrderDto>();
Mapper.CreateMap<MobileOrder, OrderDto>();
// 执行映射
var order = new PCOrder() { Referrer = "天猫" };
var mapped = Mapper.Map<OrderDto>(order);
Console.WriteLine(mapped.Referrer);
执行结果如下:

注意在我们的映射配置中,我们已经忽略了Referrer(因为Order基类中不存在这个属性),但是在基类的映射中,惯例比忽略的属性有更高的优先级,因而属性仍然得到了映射。
AutoMapper(六)的更多相关文章
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)
前言 大家好,我是Rector 又是星期五,很兴奋,很高兴,很high...啦啦啦... Rector在图享网又和大家见面啦!!!上一篇<一步一步创建ASP.NET MVC5程序[Reposit ...
- DTO学习系列之AutoMapper(六)----EntityFramework和AutoMapper的婚后生活
写在前面 我到底是什么? 越界的可怕 做好自己 后记 文章标题主要关键字:mapping DTOs to Entities,注意并不是“Entities to DTOs”,表示实体对象到DTO的转换, ...
- 【道德经】漫谈实体、对象、DTO及AutoMapper的使用
写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...
- C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用
前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...
- C#进阶系列——DDD领域驱动设计初探(六):领域服务
前言:之前一直在搭建项目架构的代码,有点偏离我们的主题(DDD)了,这篇我们继续来聊聊DDD里面另一个比较重要的知识点:领域服务.关于领域服务的使用,书中也介绍得比较晦涩,在此就根据博主自己的理解谈谈 ...
- 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](七)
前言 大家好,我依旧是你们的老朋友Rector,很高兴又在周五的时候准时和大家见面. Rector的系列文章[一步一步创建ASP.NET MVC5程序[Repository+Autofac+Autom ...
- 8分钟学会使用AutoMapper
一.什么是AutoMapper与为什么用它. 它是一种对象与对象之间的映射器,让AutoMapper有意思的就是在于它提供了一些将类型A映射到类型B这种无聊的实例,只要B遵循AutoMapper已经建 ...
- c# AutoMapper 使用方式和再封装
安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可. 我从网上找了一些资料, 参考网址:http://blog.csdn.net/csethcrm/a ...
- c# automapper 使用(一)
一.最简单的用法 有两个类User和UserDto public class User { public int Id { get; set; } public string Name { get; ...
随机推荐
- C++ 可配置的类工厂
项目中常用到工厂模式,工厂模式可以把创建对象的具体细节封装到Create函数中,减少重复代码,增强可读和可维护性.传统的工厂实现如下: class Widget { public: virtual i ...
- InnoDB关键特性学习笔记
插入缓存 Insert Buffer Insert Buffer是InnoDB存储引擎关键特性中最令人激动与兴奋的一个功能.不过这个名字可能会让人认为插入缓冲是缓冲池中的一个组成部分.其实不然,Inn ...
- windows环境下sublime的nodejs插件详细安装图解
前面的话 搜索了好多文档后,才成功地安装了sublime text3的nodejs插件.为了存档,也为了方便有同样需求的朋友,将其安装过程详细记录如下 安装nodejs 虽然nodejs官网提供了 ...
- 使用Oracle官方巡检工具ORAchk巡检数据库
ORAchk概述 ORAchk是Oracle官方出品的Oracle产品健康检查工具,可以从MOS(My Oracle Support)网站上下载,免费使用.这个工具可以检查Oracle数据库,Gold ...
- 12、Struts2表单重复提交
什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...
- 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式
上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...
- UWP开发之Mvvmlight实践九:基于MVVM的项目架构分享
在前几章介绍了不少MVVM以及Mvvmlight实例,那实际企业开发中将以那种架构开发比较好?怎样分层开发才能节省成本? 本文特别分享实际企业项目开发中使用过的项目架构,欢迎参照使用!有不好的地方欢迎 ...
- trigger事件模拟
事件模拟trigger 在操作DOM元素中,大多数事件都是用户必须操作才会触发事件,但有时,需要模拟用户的操作,来达到效果. 需求:页面初始化时触发搜索事件并获取input控件值,并打印输出(效果图如 ...
- Atitit.研发团队的管理原则---立长不立贤与按资排辈原则
Atitit.研发团队的管理原则---立长不立贤与按资排辈原则 1. 组织任命原则概述1 2. 历史的角度看,大部分组织使用的立长不立贤原则1 3. 论资排辈 立长不立贤原则1 3.1. 资格和辈分是 ...
- 跨域问题,前端主动向后台发送cookie
跨域是什么? 从一个域名的网页访问另一个域名的资源,就会出现跨域.只要协议.端口.域名有一个不同就会出现跨域 例如: 1.协议不同 http://www.baidu.com:80 和 https:/ ...