返回总目录


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(六)的更多相关文章

  1. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)

    前言 大家好,我是Rector 又是星期五,很兴奋,很高兴,很high...啦啦啦... Rector在图享网又和大家见面啦!!!上一篇<一步一步创建ASP.NET MVC5程序[Reposit ...

  2. DTO学习系列之AutoMapper(六)----EntityFramework和AutoMapper的婚后生活

    写在前面 我到底是什么? 越界的可怕 做好自己 后记 文章标题主要关键字:mapping DTOs to Entities,注意并不是“Entities to DTOs”,表示实体对象到DTO的转换, ...

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

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

  4. C#进阶系列——DDD领域驱动设计初探(五):AutoMapper使用

    前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...

  5. C#进阶系列——DDD领域驱动设计初探(六):领域服务

    前言:之前一直在搭建项目架构的代码,有点偏离我们的主题(DDD)了,这篇我们继续来聊聊DDD里面另一个比较重要的知识点:领域服务.关于领域服务的使用,书中也介绍得比较晦涩,在此就根据博主自己的理解谈谈 ...

  6. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](七)

    前言 大家好,我依旧是你们的老朋友Rector,很高兴又在周五的时候准时和大家见面. Rector的系列文章[一步一步创建ASP.NET MVC5程序[Repository+Autofac+Autom ...

  7. 8分钟学会使用AutoMapper

    一.什么是AutoMapper与为什么用它. 它是一种对象与对象之间的映射器,让AutoMapper有意思的就是在于它提供了一些将类型A映射到类型B这种无聊的实例,只要B遵循AutoMapper已经建 ...

  8. c# AutoMapper 使用方式和再封装

    安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可. 我从网上找了一些资料, 参考网址:http://blog.csdn.net/csethcrm/a ...

  9. c# automapper 使用(一)

    一.最简单的用法 有两个类User和UserDto public class User { public int Id { get; set; } public string Name { get; ...

随机推荐

  1. 先说IEnumerable,我们每天用的foreach你真的懂它吗?

    我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq to Object中要返回IEnumerable? 接下来,先开始我们的正 ...

  2. Ubuntu下使用nvm

    写在前面:刚写着写着博客就跨年了,希望新的一年大家万事如意,一切向"前"看! 安装 wget -qO- https://raw.githubusercontent.com/crea ...

  3. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  4. python自动化测试(2)-自动化基本技术原理

    python自动化测试(2) 自动化基本技术原理 1   概述 在之前的文章里面提到过:做自动化的首要本领就是要会 透过现象看本质 ,落实到实际的IT工作中就是 透过界面看数据. 掌握上面的这样的本领 ...

  5. 匹夫细说C#:庖丁解牛迭代器,那些藏在幕后的秘密

    0x00 前言 在匹夫的上一篇文章<匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置>的最后,匹夫以总结和后记的方式涉及到一部分迭代器的知识.但是觉得还是不够过瘾,很多需要说清楚 ...

  6. 一次修改闭源 Entity Provider 程序集以兼容新 EntityFramework 的过程

    读完本文你会知道,如何在没有源码的情况下,直接修改一个 DLL 以去除 DLL 上的强命名限制,并在该程序集上直接添加你的“友元程序集(一种特殊的 Attribute,将它应用在程序集上,使得程序集内 ...

  7. 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法

    若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...

  8. SQL Server-聚焦计算列或计算列持久化查询性能(二十二)

    前言 上一节我们详细讲解了计算列以及计算列持久化的问题,本节我们依然如前面讲解来看看二者查询性能问题,简短的内容,深入的理解,Always to review the basics. 持久化计算列比非 ...

  9. 一篇文章看懂TPCx-BB(大数据基准测试工具)源码

    TPCx-BB是大数据基准测试工具,它通过模拟零售商的30个应用场景,执行30个查询来衡量基于Hadoop的大数据系统的包括硬件和软件的性能.其中一些场景还用到了机器学习算法(聚类.线性回归等).为了 ...

  10. 免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)

    前面介绍了六种.NET组件,其中有一种组件是写文件的压缩和解压,现在介绍另一种文件的解压缩组件SharpZipLib.在这个组件介绍系列中,只为简单的介绍组件的背景和简单的应用,读者在阅读时可以结合官 ...