你的位置:首页 > ASP.net教程

[ASP.net教程]AutoMapper(五)


返回总目录


Dynamic和ExpandoObject映射

AutoMapper不用任何配置就可以从dynamic(动态)对象映射或映射到dynamic对象。

namespace FifthAutoMapper{  //定义一个Person类  public class Person  {    public int Age { get; set; }    public string Name { get; set; }  }  //主程序  class Program  {    static void Main(string[] args)    {      //不需要CreateMap同样可以映射,这就是所谓的“零配置”      //Mapper.CreateMap<MyDynamicClass, Person>().ReverseMap();      //将一个动态对象映射到一个普通实例      dynamic dynamicObj = new ExpandoObject();//ExpandoObject对象包含可在运行时动态添加或移除的成员      dynamicObj.Age = 103;      dynamicObj.Name = "tkb至简";      Person person = Mapper.Map<Person>(dynamicObj);      Console.WriteLine("person.Age={0},Name={1}", person.Age, person.Name);      //将一个普通实例映射到动态对象      dynamic dynamicObj2= Mapper.Map<ExpandoObject>(person);      Console.WriteLine("dynamicObj2.Age={0},Name={1}", dynamicObj2.Age, dynamicObj2.Name);      Console.Read();    }  }}

关于这个程序的说明,代码中都注释得很清楚了,不需再多做解释。

扁平化

对象与对象之间的映射的通常用法就是将一个复杂的模型压扁成一个更为简单的模型。为了演示需要,我这里定义几个类,代码如下:

namespace FifthAutoMapper{  public class Order  {    public Customer Customer { get; set; }    public decimal GetTotal()    {      return 100M;    }  }  public class Customer  {    public string Name { get; set; }  }  public class OrderDto  {    public string CustomerName { get; set; }    public decimal Total { get; set; }  }}

Order类:就是一个普通的订单类,当然,实际的项目肯定会有很多的属性,这里为了方便演示,只保留一个属性和一个方法。

Customer类:顾客类,定义了顾客的姓名。

OrderDto类:Order扁平化后的类,包含了特定需求的数据。

官方定义:当使用CreateMap方法在AutoMapper中配置源类型和目标类型时,配置器会尝试将源上的属性和方法匹配到目标的属性上。如果目标属性的任何属性在源类型的属性,方法或者以Get为前缀的方法都不存在,那么AutoMapper会把目标成员的名称(按照PascalCase惯例)分割成独立的单词。

下面测试一下,在Main方法中添加如下代码:

Mapper.CreateMap<Order, OrderDto>();var order = new Order(){  Customer = new Customer() {Name = "tkb至简"},};var orderDto= Mapper.Map<OrderDto>(order);Console.WriteLine(orderDto.CustomerName);Console.WriteLine(orderDto.Total);

image

虽然前面的博客已经说了很多了,但这里还是在啰嗦地解释一下。

我们在AutoMapper的Createmap方法中配置了类型映射。AutoMapper只能映射它知道的类型对,因此我们使用CreateMap显示地注册了源/目标类型对。为了执行映射,我们使用Map方法。

在OrderDto类中,Total属性匹配到了Order上的GetTotal方法。CustomerName属性匹配到了Order上的Customer.Name属性。总之,只要合适地命名目标类型属性,我们就不必配置单独的属性匹配。