十年河东,十年河西,莫欺少年穷。

学无止境,精益求精。

不扯犊子,直接进入正题:

AutoMapper自动映射常用于EF中,能很好的解决DTO和Model之间相互映射的问题。在未使用AutoMapper之前,我们回顾下传统的对象相互映射的方法。

首先贴出本节要用到的DTO,学生表及系表,他们之间存在主外键关系!如下:

    public partial class Dept
{
public Dept()
{
this.Student = new HashSet<Student>();
} public int Id { get; set; }
public string deptNum { get; set; }
public string deptName { get; set; } public virtual ICollection<Student> Student { get; set; }
} public partial class Student
{
public int Id { get; set; }
public string StuNum { get; set; }
public string deptNum { get; set; }
public string StuName { get; set; }
public string StuSex { get; set; }
public Nullable<System.DateTime> AddTime { get; set; } public virtual Dept Dept { get; set; }
}

假设,现在要求将得到的学生对象转化为Model

新建学生对象Model

    public class StudentModel
{
public int Id { get; set; }
public string StuNum { get; set; }
public string deptNum { get; set; }
public string StuName { get; set; }
public string StuSex { get; set; }
public Nullable<System.DateTime> AddTime { get; set; }
}

传统方法如下:

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SM = context.Student.Where(A => A.StuNum == "").FirstOrDefault();
if (SM != null)
{
var StudetM = new StudentModel()
{
Id = SM.Id,
StuName = SM.StuNum,
StuNum = SM.StuNum,
StuSex = SM.StuSex,
deptNum = SM.deptNum,
AddTime = SM.AddTime
};
}
}
return View();
}
}

传统方法实现相互映射存在一个弊端,如果数据表字段特别多,那么,试问你需要写多少行代码?

OK,AutoMapper闪亮登场,那么如果使用AutoMapper需要写什么样的代码呢?

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SM = context.Student.Where(A => A.StuNum == "").FirstOrDefault();
if (SM != null)
{
StudentModel StudentM = Mapper.DynamicMap<StudentModel>(SM);
}
}
return View();
}
}

由上述代码可知,其相互映射只需一行代码搞定。这里需要注意,你定义的Model层个字段属性要和DTO层字段属性一致。

OK,那如果需要转化一个泛型集合呢?

传统方法如下:

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SMList = context.Student.Where(A => A.StuName.Contains("陈")).ToList();
if (SMList != null&&SMList.Count>)
{
foreach (var SM in SMList)
{
var StudetM = new StudentModel()
{
Id = SM.Id,
StuName = SM.StuNum,
StuNum = SM.StuNum,
StuSex = SM.StuSex,
deptNum = SM.deptNum,
AddTime = SM.AddTime
};
}
}
}
return View();
}
}

那么,AutoMapper是否可以做到呢?

当然,可以...

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SMList = context.Student.Where(A => A.StuName.Contains("陈")).ToList();
if (SMList != null && SMList.Count > )
{
List<StudentModel> StudentM = Mapper.DynamicMap<List<StudentModel>>(SMList);
}
}
return View();
}
}

有上述代码可知,是不是连Foreach都省了?

哈哈,OK,这些都是些基础功能,咱们继续深究。

如果需要映射导航属性对应表中的字段怎么写呢?

我们将StudentModel修改成如下:

如果要得到系名称 deptName ,我们就要用到EF的懒加载。关于用EF懒加载时要注意的事项,大家可参考博客: EF性能优化-有人说EF性能低,我想说:EF确实不如ADO.NET,当然本节也会详细说明。

首先用传统方法实现如下:

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SM = context.Student.Where(A => A.StuNum == "").FirstOrDefault();
if (SM != null)
{
var StudetM = new StudentModel()
{
Id = SM.Id,
StuName = SM.StuNum,
StuNum = SM.StuNum,
StuSex = SM.StuSex,
deptNum = SM.deptNum,
AddTime = SM.AddTime,
deptName=SM.Dept.deptName
};
}
}
return View();
}
}

传统方法变化不大,那么,用AutoMapper怎么实现呢?

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SM = context.Student.Where(A => A.StuNum == "").FirstOrDefault();
AutoMapper.Mapper.CreateMap<Student, StudentModel>().ForMember(dest => dest.deptName, opts => opts.MapFrom(src => src.Dept.deptName));
var model = AutoMapper.Mapper.Map<StudentModel>(SM);
}
return View();
}
}

由上述方法可知,使用AutoMapper方法进行映射,需要指定目标字段dest.deptName 以及 源字段 src.Dept.deptName,关于AutoMapper的详细用法及说明大家可参考:【来龙去脉系列】AutoMapper一款自动映射框架

在这里,我要告诫大家关于使用懒加载的注意事项,如果你不注意,那么你写的代码效率有可能将会非常低。

如上述两种方法,我们来监控下生成的SQL语句:(关于是如果监控生成的SQL语句,大家可参考我的博客:MiniProfiler工具介绍(监控EF生成的SQL语句)--EF,迷你监控器,哈哈哈

生成了2条SQL语句:

OK,仅仅生成两条SQL语句还可以接受,但是如果你的项目数据表关系比较复杂,有很多导航属性时,就会生成很多SQL语句,会产生极大的性能问题。

那么关于懒加载的问题怎么解决呢?还好,EF中有Include,在使用Include时需要引入using System.Data.Entity;

将上边的程序修改成如下:

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
var SMList = context.Student.Include(A=>A.Dept).Where(A => A.StuName.Contains("陈")).ToList();
AutoMapper.Mapper.CreateMap<Student, StudentModel>()
.ForMember(dest => dest.deptName, opts => opts.MapFrom(src => src.Dept.deptName));
var modelList = AutoMapper.Mapper.Map<List<StudentModel>>(SMList);
}
return View();
}
}

使用Include,其实相当于声明弃用懒加载,这里使用显示加载!

OK,关于使用AutoMapper应用懒加载的方法讲完了。正如上述所说:AutoMapper是将DTO映射成Model,如果反过来映射是否可行呢?

还好,AutoMapper提供了.ReverseMap();方法,将Model映射成DTO,如下:

        public ActionResult Index()
{
var profiler = MiniProfiler.Current; using (profiler.Step("查询Student的数据"))
{
using (BingFaTestEntities context = new BingFaTestEntities())
{
StudentModel M = new StudentModel()
{
StuName = "陈星辰",
AddTime = DateTime.Now,
deptNum = "",
StuNum = "",
StuSex = "男"
};
Student Sm = new Student();
AutoMapper.Mapper.CreateMap<StudentModel, Student>().ReverseMap();
Sm = AutoMapper.Mapper.Map<Student>(M);
context.Student.Add(Sm);
context.SaveChanges();
}
return View();
}
}

OK。截止到这里,关于AutoMapper的基础用法也就讲完了,本人能力有限,如有未提及之处,请大家多多指点。希望大家喜欢!

@陈卧龙的博客

AutoMapper自动映射的更多相关文章

  1. automapper 自动映射 集成asp.net Core2.1

    学习博文:https://www.cnblogs.com/yan7/p/8085410.html 1.使用nuget 安装 <PackageReference Include="Aut ...

  2. Asp.NetCore 3.1 使用AutoMapper自动映射转换实体 DTO,Data2ViewModel

    1:什么是AutoMapper? 下面为AutoMapper官方的解释: AutoMapper是一个对象-对象映射器.对象-对象映射通过将一种类型的输入对象转换为另一种类型的输出对象来工作. 使Aut ...

  3. AutoMapper 自动映射工具

    先引用对应的DLL. 11.转换匿名对象 结合LINQ映射新的实体类. using System;using System.Collections.Generic;using System.Linq; ...

  4. 【来龙去脉系列】AutoMapper一款自动映射框架

    前言 通常在一个应用程序中,我们开发人员会在两个不同的类型对象之间传输数据,通常我们会用DTOs(数据传输对象),View Models(视图模型),或者直接是一些从一个service或者Web AP ...

  5. 打造强大的BaseModel(2):让Model实现自动映射,将字典转化成Model

    打造强大的BaseModel(1):让Model自我描述 这篇文章将讲述Model一项更高级也最常用的功能,让Model实现自动映射–将字典转化成Model(所有代码全由Swift实现) 将JSON转 ...

  6. 反射+自定义注解---实现Excel数据列属性和JavaBean属性的自动映射

    简单粗暴,直奔主题.   需求:通过自定义注解和反射技术,将Excel文件中的数据自动映射到pojo类中,最终返回一个List<pojo>集合? 今天我只是通过一位使用者的身份来给各位分享 ...

  7. 禁用自动映射的 Exchange 邮箱

    客户最近询问他们无法从用户的Outlook配置文件中删除邮箱.在这种情况下,它们是共享邮箱,并出现在Outlook的左窗格中.但原因和解决方法同样适用于用户邮箱.并且 无论用户邮箱在本地 Exchan ...

  8. .NET之AutoMapper对象映射工具运用

    AutoMapper对象映射工具:主要是将某一个实体转成另一个实体. 1.引用NuGet包;搜索:AutoMapper 2.创建实体类 using System; using System.Colle ...

  9. Mybatis映射文件的自动映射与手动映射问题

    Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同功能的 JDBC 代码进行对比,你会 ...

随机推荐

  1. (后端)注意hibernate中对象的set方法修改数据库

    2017-10-16 公司里面其他人发现了一个问题,五粮液金品库存出现了问题,删除了库存也没还回来,一瓶一千多.而且在我的功能块,在我看出货详情的时候,诡异的事情发生了,第一眼看上去没问题呀,刷新了一 ...

  2. Paxos 算法 :消息传递一致性

    网络上有很多关于优秀的关于Paxos 算法的文章,我下面进行整理搜集一下: 分布式理论之一:Paxos算法的通俗理解 维基的简介:Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 L ...

  3. 搜索插入位置的golang实现

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 输入: [,,,], 输出: 输入: [,,,] ...

  4. Axure RP Pro7.0的key注册码加汉化非破解

    上次我们刚分享过Axure RP Pro6.5 key注册码加汉化非破解,我还要分享一个Axure RP Pro7.0的key注册码加汉化,非破解哦. 当然方法还是不变,先用下面的密钥激活.用户名就是 ...

  5. 控件_ProgressBar

    进度条的风格: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:andr ...

  6. Java虚拟机4:Java对象创建和对象访问

    1.对象创建 Java是一门面向对象的语言,Java程序运行过程中无时无刻都有对象被创建出来.在语言层面上,创建对象(克隆.反序列化)就是一个new关键字而已,但是虚拟机层面上却不是如此.看一下在虚拟 ...

  7. WPFの操作文件浏览框几种方式

    方式1: 使用win32控件OpenFileDialog Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog ...

  8. [android]android Task 任务 简介

    http://blog.csdn.net/guomeijuan916/article/details/8121468 关于Android中的组件和应用,之前涉及,大都是静态的概念.而当一个应用运行起来 ...

  9. PHP开发api接口安全验证方法一

    前台想要调用接口,需要使用几个参数生成签名.时间戳:当前时间随机数:随机生成的随机数 签名:特定方法生成的sign签名 算法规则在前后台交互中,算法规则是非常重要的,前后台都要通过算法规则计算出签名, ...

  10. (二 -2) 天猫精灵接入Home Assistant-自动发现Mqtt设备

    参考中文教程:  https://www.hachina.io/docs/7230.html 英文官网 两个温度传感器:https://www.home-assistant.io/docs/mqtt/ ...