详解c# AutoMapper 使用方式

安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可。

先说说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工具。

下载了个demo,然后自己又写了一遍,我把AutoMapper 的使用分为两种:

1、viewmodel与实体的字段名字是一致的,viewmodel的字段可以比实体中的字段少,但是不能多。

还有一种情况是:源实体中的字段名字是Getxxx,那么viewmodel中对应的字段可以是xxx,也会自动对应赋值,比如我写的demo中源实体中GetA,viewmodel中的A;

再有一种情况就是实体中的实体赋值,在我写的这个例子中,源实体中包含的实体类字段为Sub,里面包含的字段名字为Age,

那么destmodel中对应的字段名字可以是:SubAge,那么automapper就可以自动为你赋值了,大家看最后的运行结果。

给大家看下我建的源实体:

  public class Source1
  {
    public string Name { set; get; }

    public string GetA { set; get; }
    public string GetD { set; get; }

    public string SetB { set; get; }

    public string c { set; get; }

    public SubSource1 Sub { set; get; }
  }

  public class SubSource1
  {
    public string Age { set; get; }

  }

还有viewmodel(要转化成为你想要的模型):

  public class Dest1
  {
    public string Name { set; get; }

    public string A { set; get; }

    public string C { set; get; }

    public string SubAge { set; get; }

    public string D { set; get; }
  }

我封装的扩展方法:

    /// <summary>
    /// 类型映射,默认字段名字一一对应
    /// </summary>
    /// <typeparam name="TDestination">转化之后的model,可以理解为viewmodel</typeparam>
    /// <typeparam name="TSource">要被转化的实体,Entity</typeparam>
    /// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
    /// <returns>转化之后的实体</returns>
    public static TDestination MapTo<TDestination, TSource>(this TSource source)
      where TDestination:class
      where TSource :class
    {
      if (source == null) return default(TDestination);
      var config = new MapperConfiguration(cfg => cfg.CreateMap<TDestination, TSource>());
      var mapper = config.CreateMapper();
      return mapper.Map<TDestination>(source);
    }

使用方式:

        var source1 = new Source1
        {
          Name = "source",
          Sub = new SubSource1 { Age = "25" },
          c = "c",
          GetA = "A",
          SetB = "B"
        };

        var destViewModel = source1.MapTo<Dest1, Source1>();

运行结果:

2.viewmodel与实体字段名字没有全部对应,只有几个字段的名字和源实体中的字段名字是一样的,其他的字段是通过实体中的几个字段组合或者是格式或者是类型转化而来的,

使用方法:不能再使用这个扩展方法了,只能自己额外写代码,代码如下:

        var config2 = new MapperConfiguration(
          cfg => cfg.CreateMap<SourceUser, DestUser2>()
            .ForMember(d => d.DestName, opt => opt.MapFrom(s => s.Name))  //指定字段一一对应
            .ForMember(d => d.Birthday, opt => opt.MapFrom(src => src.Birthday.ToString("yy-MM-dd HH:mm")))//指定字段,并转化指定的格式
            .ForMember(d => d.Age, opt => opt.Condition(src => src.Age > 5))//条件赋值
            .ForMember(d => d.A1, opt => opt.Ignore())//忽略该字段,不给该字段赋值
            .ForMember(d => d.A1, opt => opt.NullSubstitute("Default Value"))//如果源字段值为空,则赋值为 Default Value
            .ForMember(d => d.A1, opt => opt.MapFrom(src => src.Name + src.Age * 3 + src.Birthday.ToString("d"))));//可以自己随意组合赋值
        var mapper2 = config2.CreateMapper();

注释中都包含了平时常用的几种情况,其他的我就没有再写。

下面再给大家把list转化的扩展方法代码贴上:

    /// <summary>
    /// 集合列表类型映射,默认字段名字一一对应
    /// </summary>
    /// <typeparam name="TDestination">转化之后的model,可以理解为viewmodel</typeparam>
    /// <typeparam name="TSource">要被转化的实体,Entity</typeparam>
    /// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
    /// <returns>转化之后的实体列表</returns>
    public static IEnumerable<TDestination> MapToList<TDestination, TSource>(this IEnumerable<TSource> source)
      where TDestination : class
      where TSource : class
    {
      if (source == null) return new List<TDestination>();
      var config = new MapperConfiguration(cfg => cfg.CreateMap<TDestination, TSource>());
      var mapper = config.CreateMapper();
      return mapper.Map<List<TDestination>>(source);
    }

同样的使用方式:

        var source1 = new Source1
        {
          Name = "source",
          Sub = new SubSource1 { Age = "25" },
          c = "c",
          GetA = "A",
          SetB = "B"
        };
var source3 = new Source1
        {
          Name = "source3",
          Sub = new SubSource1 { Age = "253" },
          c = "c3",
          GetA = "A3",
          SetB = "B3"
        };
        var sourceList = new List<Source1> { source1, source3 };
        var destViewModelList = sourceList.MapToList<Dest1, Source1>();

运行结果:

以上就是我个人所得,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • .NET Core中依赖注入AutoMapper的方法示例

    本文主要介绍了关于.NET Core中依赖注入AutoMapper的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: 最近在 review 代码时发现同事没有像其他项目那样使用 AutoMapper.Mapper.Initialize() 静态方法配置映射,而是使用了依赖注入 IMapper 接口的方式 services.AddSingleton<IMapper>(new Mapper(new MapperConfiguration(cfg => { cfg.Cr

  • Automapper实现自动映射的实例代码

    出于安全考虑,在后台与前台进行数据传输时,往往不会直接传输实体模型,而是使用Dto(Data transfer object 数据传输对象),这样在后台往前台传递数据时可以省略不必要的信息,只保留必要的信息,大大增强数据安全性. 下面给出两个相互对应的关系模型User.UserDto public class User { private const int NameMaxLength = 20; private const int PassWordMaxLength = 16; [Key] p

  • .NET CORE中使用AutoMapper进行对象映射的方法

    简介 AutoMapper uses a fluent configuration API to define an object-object mapping strategy. AutoMapper uses a convention-based matching algorithm to match up source to destination values. AutoMapper is geared towards model projection scenarios to flat

  • 五步掌握OOM框架AutoMapper基本使用

    写在前面 OOM顾名思义,Object-Object-Mapping实体间相互转换,AutoMapper也是个老生常谈了,其意义在于帮助你无需手动的转换简单而又麻烦的实体间关系,比如ViewModel和entity的转换,SearchModel和Entity的转换,我这篇分享的意义在于,网上大多数的分享都是几年前的,很多方法已经被废弃,到了编译器里会告诉你该方法已经过时,废弃的,不建议使用的,比如Mapper.CreateMap等方法,当然老司机大多数直接就去github看文档了,或者googl

  • 详解c# AutoMapper 使用方式

    安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可. 先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对象进行合理封装,从而不会将领域对象的行为过分暴露给表现层 2.DTO是面向UI的需求而设计的,而领域模型是面向业务而设计的.因此DTO更适合于和表现层的交互,通过DTO我们实现了表现层与领域Mod

  • spring、mybatis 配置方式详解(常用两种方式)

    在之前的文章中总结了三种方式,但是有两种是注解sql的,这种方式比较混乱所以大家不怎么使用,下面总结一下常用的两种总结方式: 一. 动态代理实现 不用写dao的实现类 这种方式比较简单,不用实现dao层,只需要定义接口就可以了,这里只是为了记录配置文件所以程序写的很简单: 1.整体结构图: 2.三个配置文件以及一个映射文件 (1).程序入口以及前端控制器配置 web.xml <?xml version="1.0" encoding="UTF-8"?> &

  • ubuntu 16.04安装redis的两种方式教程详解(apt和编译方式)

    ubuntu 16.04安装redis的两种方式教程如下所示: 方式一 :apt安装 在 Ubuntu 系统安装 Redi 可以使用以下命令: $sudo apt-get update $sudo apt-get install redis-server 启动 Redis $ redis-server 查看 redis 是否启动? $ redis-cli 以上命令将打开以下终端: redis 127.0.0.1:6379> 127.0.0.1 是本机 IP ,6379 是 redis 服务端口.

  • 详解Angular5路由传值方式及其相关问题

    目前Angular已经升级到了稳定版本Angular5,这次升级更小更快以及更稳定!路由可以说是Angular甚至是单页应用的核心部分了吧!在angularjs中的路由最大的缺点就是无法嵌套路由,在Angular中解决了这个问题!在Angular中路由不仅仅是页面跳转,其中还有一项叫英雄列表跳转英雄详情!在诸多的列表,不可能给每个英雄做一个详情页,于是乎路由参数起到作用了!通过路由传入参数识别那个英雄的详情! 现在对于路由传值进行详解,首先一种方式是官网的导航到详情的单值id传入,另一种是多数据

  • 基于YUV 数据格式详解及python实现方式

    YUV 数据格式概览 YUV 的原理是把亮度与色度分离,使用 Y.U.V 分别表示亮度,以及蓝色通道与亮度的差值和红色通道与亮度的差值.其中 Y 信号分量除了表示亮度 (luma) 信号外,还含有较多的绿色通道量,单纯的 Y 分量可以显示出完整的黑白图像.U.V 分量分别表示蓝 (blue).红 (red) 分量信号,它们只含有色彩 (chrominance/color) 信息,所以 YUV 也称为 YCbCr,C 意思可以理解为 (component 或者 color). 维基百科上的 RGB

  • 详解react组件通讯方式(多种)

    1.父组件向子组件传值 父组件向子组件传值一般采用props属性传递 父组件: import React from 'react' import Child from './Child' const dataList = [ { id: '001', value: '张三' }, { id: '002', value: '李四' } ] const Parent = props => { return ( <ul> <Child dataList={dataList}><

  • 详解Python prometheus_client使用方式

    背景说明 服务部署在阿里云的K8s上,配置了基于Prometheus的Grafana监控.原本用的是自定义的Metrics接口统计,上报一些字段,后面发现Prometheus自带的监控非常全面好用,适合直接抓取统计,所以做了一些改变. Python prometheus-client 安装 pip install prometheus-client Python封装 # encoding: utf-8 from prometheus_client import Counter, Gauge, S

  • 详解Java两种方式简单实现:爬取网页并且保存

    对于网络,我一直处于好奇的态度.以前一直想着写个爬虫,但是一拖再拖,懒得实现,感觉这是一个很麻烦的事情,出现个小错误,就要调试很多时间,太浪费时间. 后来一想,既然早早给自己下了保证,就先实现它吧,从简单开始,慢慢增加功能,有时间就实现一个,并且随时优化代码. 下面是我简单实现爬取指定网页,并且保存的简单实现,其实有几种方式可以实现,这里慢慢添加该功能的几种实现方式. UrlConnection爬取实现 package html; import java.io.BufferedReader; i

  • 详解springMVC两种方式实现多文件上传及效率比较

    springMVC实现多文件上传的方式有两种,一种是我们经常使用的以字节流的方式进行文件上传,另外一种是使用springMVC包装好的解析器进行上传.这两种方式对于实现多文件上传效率上却有着很大的差距,下面我们通过实例来看一下这两种方式的实现方式,同时比较一下在效率上到底存在着多大的差距. 1.下载相关jar包.需要引入的jar出了springMVC的jar包外,还需要引入com.springsource.org.apache.commons.fileupload-1.2.0.jar和com.s

  • 详解如何全注解方式构建SpringMVC项目

    简述 SpringBoot对Spring的的使用做了全面的封装,使用SpringBoot大大加快了开发进程,但是如果不了解Spring的特性,使用SpringBoot时会有不少问题 目前网上流传使用IDEA比Eclipse效率更加高,在搭建项目时,也尝试使用IDEA,但是由于习惯问题,最终还是使用了Eclipse,以后也别再折腾了,专注于开发本身更加重要 这是个简单的SpringMVC项目,目的在于帮助理解Spring4的SpringMVC的搭建,采用注解方式.项目简单得不能再简单,采用tomc

随机推荐