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

[ASP.net教程]Auto Mapper03


  经过上一篇博客的学习,大体了解了Auto Mapper的运行机制和操作流程。我们下来学习下,AutoMapper里面具体的一些东西。

一:规则    

  当我们使用AutoMapper创建实体和外部Model的映射的时候,AutoMapper的匹配原值有三种方式。

   #:名称相同的属性进行映射,不区分大小写。

   #:带Get前缀的方法进行映射。<例子(Order和OrderDto):Order中的GetTotal分割成Get和Total,Total会和Dto中的进行匹配。>

   #:目标类型属性分割。<CustomerName也是一样,是分割的,Name回合后面的匹配。>

Order类

  /// <summary>  /// 订单  /// </summary>  public class Order  {    public Customer Customer { get; set; }    public decimal GetTotal()    {      return 10*10;    }  }  /// <summary>  /// 顾客  /// </summary>  public class Customer  {    public string Name { get; set; }  }

OrderDto类

  /// <summary>  /// 数据传输对象Dto  /// </summary>  public class OrderDto  {    public string CustomerName { get; set; }    public decimal Total { get; set; }  }

这里我们将Order转换为OrderDto,也就是Order里面的Customer中的Name转换为CustomerName;

      Order dto=new Order()      {        Customer = new Customer{Name = "ahui"},              };      //配置      Mapper.CreateMap<Order, OrderDto>();              //执行      var order = Mapper.Map<Order,OrderDto>(dto);      Console.WriteLine(order.CustomerName);      Console.ReadKey();

image

二:AutoMapper中利用Condition来进行判断,从而选择是否进行转换。

订单

  /// <summary>  /// 订单  /// </summary>  public class Order  {    public Order()    {      Number = 100;    }    //订单数量    public int Number { get; set; }  }

订单DTO

  /// <summary>  /// 数据传输对象Dto  /// </summary>  public class OrderDto  {    public OrderDto()    {      Num = 90;    }    public int Num { get; set; }  }

Main()方法

      //配置  通过Condition来规定Order中的值是0~12之间。在这个之间就可以进行映射,不是就不映射。输出其默认值10;      Mapper.CreateMap<Order,OrderDto>().ForMember(x=>x.Num,mo=>mo.Condition(s=>s.Number >0&& s.Number <12)).ForMember(x=>x.Num,mo=>mo.MapFrom(x=>x.Number));      //执行映射      var orderDto = Mapper.Map<OrderDto>(new Order(){Number = 10});      var p1 = Mapper.Map<OrderDto>(new Order(){Number = 20});      Console.WriteLine(orderDto.Num);     //这里输出10      Console.WriteLine(p1.Num);         //这里转换失败,结果为90.      Console.ReadKey();
image

通过Condition这个方法我们可以规定如何去转换,指定转换条件。

三:通过Initialize来增加一个配置文件。

这里增加一个配置文件,主要是防止我们以后配置文件多了,我们不必每一次都写,在需要调用配置文件即可。

1:新建一个ProFilesMapper类继承自Profile,并且实现他的方法Configuer(),这个方法就是我们在里面写配置文件的。

  /// <summary>  /// 配置文件  /// </summary>  public class ProFilesMapper:Profile  {    protected override void Configure()    {      //这里放一些CreateMap(),也就是我们之前的配置映射      //配置  通过Condition来规定Order中的值是0~12之间。在这个之间就可以进行映射,不是就不映射。输出其默认值10;      Mapper.CreateMap<Order, OrderDto>().ForMember(x => x.Num, mo => mo.Condition(s => s.Number > 0 && s.Number < 12)).ForMember(x => x.Num, mo => mo.MapFrom(x => x.Number));    }      }

2:在main()方法里面可以直接使用加载配置文件就可以实现之前的的配置了。

      //配置      Mapper.Initialize(x =>x.AddProfile<ProFilesMapper>());

这样就可以实现配置了。

      //配置      Mapper.Initialize(x =>x.AddProfile<ProFilesMapper>());      //执行映射      var orderDto = Mapper.Map<OrderDto>(new Order() { Number = 10 });      var p1 = Mapper.Map<OrderDto>(new Order() { Number = 20 });      Console.WriteLine(orderDto.Num);     //这里输出10      Console.WriteLine(p1.Num);         //这里转换失败,结果为90.      Console.ReadKey();
四:实现命名惯例
只需要配置中添加下面两句代码
    protected override void Configure()    {      //这里放一些CreateMap(),也就是我们之前的配置映射      //配置  通过Condition来规定Order中的值是0~12之间。在这个之间就可以进行映射,不是就不映射。输出其默认值10;      Mapper.CreateMap<Order, OrderDto>().ForMember(x => x.Num, mo => mo.Condition(s => s.Number > 0 && s.Number < 12)).ForMember(x => x.Num, mo => mo.MapFrom(x => x.Number));      //通过下面的两个设置源和目标的命名惯例 而且必须写在CreateMap后面      SourceMemberNamingConvention=new LowerUnderscoreNamingConvention();      DestinationMemberNamingConvention=new PascalCaseNamingConvention();    }    
      //配置      Mapper.Initialize(x=>x.AddProfile<ProFilesMapper>());      //执行映射      var d1 = Mapper.Map<OrderDto>(new Order()      {        MyName ="ahui"      });      Console.WriteLine(d1.my_name);      Console.ReadKey();

image

看下我们的两个属性

    public string my_name { get; set; }
    public string MyName { get; set; }
这个我觉得就是像忽略了大小写,直接就可以进行映射。

五:集合之间的映射

    这里就是在我们Mapper.Map<>(),执行映射的时候,这里我们看他们需要什么类型的,就传递什么。

配置:

      Mapper.CreateMap<Souce,Destination>();

类代码:

  public class Souce  {    public int Value { get; set; }  }  public class Destination  {    public int Value { get; set; }  }

main()方法:

      #region 示例08      //配置      Mapper.Initialize(x=>x.AddProfile<ProFilesMapper>());       //初始化,这就是将其初始化为数组      var sources = new[]      {        new Souce(){Value = 1},        new Souce(){Value = 2},         new Souce(){Value = 3},       };      //执行映射      IEnumerable<Destination> iEnumerabledDestinations = Mapper.Map<IEnumerable<Destination>>(sources);      ICollection<Destination> iCollectionDestinations = Mapper.Map<ICollection<Destination>>(sources);      IList<Destination> iListDest = Mapper.Map<IList<Destination>>(sources);      List<Destination> listDests =       Mapper.Map<List<Destination>>(sources);      Destination[] deatArrey =         Mapper.Map<Destination[]>(sources);      Console.WriteLine("******第一个转换*****");      foreach (var item in iEnumerabledDestinations)      {        Console.WriteLine(item.Value + ",,");      }            Console.WriteLine("******第二个转换*****");      foreach (var item in iCollectionDestinations)      {        Console.WriteLine(item.Value + ",,");      }      Console.WriteLine("******第三个转换*****");      foreach (var item in iListDest)      {        Console.WriteLine(item.Value + ",,");      }      Console.WriteLine("******第四个转换*****");      foreach (var item in deatArrey)      {        Console.WriteLine(item.Value + ",,");      }      Console.ReadKey();

image

我们通过这四种类型的执行映射都可以得到我们想要的结果,说明AutoMapper是成功的。

附件:

“tkb至简” http://www.cnblogs.com/farb/p/4932692.html