zoukankan      html  css  js  c++  java
  • C#使用AutoMapper6.2.2.0进行对象映射

      先说说DTO

      DTO是个什么东东?

      DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已。

      为什么要用DTO?

      1、DTO更注重数据,对领域对象进行合理封装,从而不会将领域对象的行为过分暴露给表现层

      2、DTO是面向UI的需求而设计的,而领域模型是面向业务而设计的。因此DTO更适合于和表现层的交互,通过DTO我们实现了表现层与领域Model之间的解耦,因此改动领域Model不会影响UI层

      3、DTO说白了就是数据而已,不包含任何的业务逻辑,属于瘦身型的对象,使用时可以根据不同的UI需求进行灵活的运用

      AutoMapper

      现在我们既然知道了使用DTO的好处,那么我们肯定也想马上使用它,但是这里会牵扯一个问题:怎样实现DTO和领域Model之间的转换?

      有两个思路,我们要么自己写转换代码,要么使用工具。不过就应用而言,我还是觉得用工具比较简单快捷,那就使用工具吧。其实这样的转换工具很多,不过我还是决定使用AutoMapper,因为它足够轻量级,而且也非常流行,国外的大牛们都使用它。使用AutoMapper可以很方便的实现DTO和领域Model之间的转换,它是一个强大的Object-Object Mapping工具。

      摘自让AutoMapper在你的项目里飞一会儿

      AutoMapper6.2.2.0

      AutoMapper6.2.2.0与之前的版本有些不同,那么究竟有什么不同,我们一起来实践一下:

      1.首先,使用AutoMapper6.2.2.0需要在你的项目中引用NuGet包,右键依赖项,管理NuGet程序包,然后选择浏览,搜索AutoMapper,安装,你就可以在项目中使用啦,你也可以在vs中使用打开工具-库程序包管理器-程序包管理控制平台,输入“Install-Package AutoMapper”命令,就可以把AutoMapper添加到项目中了~

      2.让我们开始使用

      (1)一个简单的映射

      首先,创建一个C#控制台应用程序,为了方便,我们在Program直接定义三个类:

      public class Student

      {

      public string Name { get; set; }

      public int Sex { get; set; }

      public string Age { get; set; }

      public DateTime Birth { get; set; }

      }

      public class Dto_Student

      {

      public string n { get; set; }

      public string s { get; set; }

      public int a { get; set; }

      public string b { get; set; }

      }

      public class V_Student

      {

      public string Name { get; set; }

      public int Sex { get; set; }

      public string Age { get; set; }

      public DateTime Birth { get; set; }

      }

      复制代码

      (2)一个简单的映射,由于Student和V_Student类字段名称一样,类型相同,所以,映射可以这么写

      //一个简单的映射

      AutoMapper.Mapper.Initialize(map => map.CreateMap<student, v_student="">());

      var stu = AutoMapper.Mapper.Map(new V_Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      var vstu = AutoMapper.Mapper.Map<v_student>(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      复制代码

      (3)那么,不同字段名称,甚至不同类型的两个类如何映射呢,那就要手动的映射相应字段了:

      //属性不同名,属性类型不同映射

      AutoMapper.Mapper.Initialize(map => map.CreateMap<student, dto_student="">()

      .ForMember(d => d.n, opt =>

      {

      opt.MapFrom(s => s.Name);

      })

      .ForMember(d => d.s, opt =>

      {

      opt.MapFrom(s => s.Sex == 1 ? "男" : "女");

      })

      .ForMember(d => d.a, opt =>

      {

      opt.MapFrom(s => Convert.ToInt32(s.Age));

      })

      .ForMember(d => d.b, opt =>

      {

      opt.MapFrom(s => s.Birth.ToString("yyyy-MM-dd"));

      })

      );

      var dto_stu = AutoMapper.Mapper.Map<dto_student>(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      var stu = AutoMapper.Mapper.Map(new Dto_Student

      {

      n = "myname",

      s = "男",

      a = 24,

      b = DateTime.Now.ToString("yyyy-MM-dd")

      });

      复制代码

      这边一运行,发现报错了,为什么呢,原来是因为,由于映射字段类型不同,无法反向映射,那么,如何再添加一个映射呢,这时候就需要用到Profile这个类,我们需要继承这个类,并在里面写下映射配置,具体如下:

      新建Dto_StudentProfile类和StudentProfile类:

      public class Dto_StudentProfile:Profile

      {

      public Dto_StudentProfile()

      {

      base.CreateMap<dto_student, student="">()

      .ForMember(s => s.Name, opt =>

      {

      opt.MapFrom(stu => stu.n);

      })

      .ForMember(s => s.Sex, opt =>

      {

      opt.MapFrom(stu => stu.s.Equals("男")?1:0);

      })

      .ForMember(s => s.Age, opt =>

      {

      opt.MapFrom(stu => stu.a.ToString());

      })

      .ForMember(s => s.Birth, opt =>

      {

      opt.MapFrom(stu =>DateTime.Parse( stu.b+" 00:00:00"));

      });

      }

      }

      public class StudentProfile:Profile

      {

      public StudentProfile()

      {

      base.CreateMap<student, dto_student="">()

      .ForMember(d => d.n, opt =>

      {

      opt.MapFrom(stu => stu.Name);

      })

      .ForMember(d => d.s, opt =>

      {

      opt.MapFrom(stu => stu.Sex == 1 ? "男" : "女");

      })

      .ForMember(d => d.a, opt =>

      {

      opt.MapFrom(stu => Convert.ToInt32(stu.Age));

      })

      .ForMember(d => d.b, opt =>

      {

      opt.MapFrom(stu => stu.Birth.ToString("yyyy-MM-dd"));

      });

      }

      }

      复制代码

      那么,我们如何使用两个配置呢?

      //配置映射

      AutoMapper.Mapper.Initialize(map => map.AddProfiles(new[] {

      typeof(Dto_StudentProfile),

      typeof(StudentProfile)

      }));

      var dto_stu = AutoMapper.Mapper.Map<dto_student>(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      var stu = AutoMapper.Mapper.Map(new Dto_Student

      {

      n = "myname",

      s = "男",

      a = 24,

      b = DateTime.Now.ToString("yyyy-MM-dd")

      });

      复制代码

      这样,我们就完成了两个不同字段名称,不同类型的映射

      (4)映射List

      如何进行实体列表的映射呢,其实,配置上并没有任何不同,只需要在使用上,换成list就可以了:

      List estu = new List();

      estu.Add(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      estu.Add(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      List<dto_student> slist = AutoMapper.Mapper.Map<list, List<dto_student>>(estu);

      复制代码

      (5)你可能觉得不太方便,那么,我们可以将AutoMapper的Initialize放到应用开始的时候运行

      Mvc项目,可以放到程序的Global中,如果是.NET Core 2.0的MVC项目,可以放到StartUp中运行:

      这边直接摘了前人的方法,有兴趣可以看一下https://www.cnblogs.com/lvlinlv/p/7344916.html

      (6)那么,你可以使用拓展的方法进行映射,这里定义一个AutoMapperHelper操作类:

      using System;

      using System.Collections;

      using System.Collections.Generic;

      using System.Text;

      namespace AutoMapperTest

      {

      public static class AutoMapperHelper

      {

      public static T MapTo(this object obj)

      {

      if (obj == null) return default(T);

      return AutoMapper.Mapper.Map(obj);

      }

      public static List MapToList(this object source)

      {

      return AutoMapper.Mapper.Map<list>(source);

      }

      }

      }

      复制代码

      这样,你就可以这么使用:

      List estu = new List();

      estu.Add(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      estu.Add(new Student

      {

      Name = "myname",

      Sex = 1,

      Age = "24",

      Birth = DateTime.Now

      });

      var slist = estu.MapToList<dto_student>();

      复制代码(编辑:雷林鹏 来源:网络)

  • 相关阅读:
    go开发环境配置
    Go环境配置
    为什么Redis集群有16384个槽【转发】
    Spring Cloud Hystrix降级处理超时时间设置
    win10下查看进程,杀死进程【转载】
    SpringCloud的各种超时时间配置效果
    解决springcloud Feign项目中遇到的timeout请求超时的问题【转载】
    数据库索引
    XML
    JDBC
  • 原文地址:https://www.cnblogs.com/pengpeng1208/p/9405374.html
Copyright © 2011-2022 走看看