automapper自动创建映射_AutoMapper自动映射-阿里云开发者社区

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

学无止境,精益求精。

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

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

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

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

public partial classDept

{publicDept()

{this.Student = new HashSet();

}public int Id { get; set; }public string deptNum { get; set; }public string deptName { get; set; }public virtual ICollection Student { get; set; }

}public partial classStudent

{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 AddTime { get; set; }public virtual Dept Dept { get; set; }

}

View Code

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

新建学生对象Model

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

public classStudentModel

{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 AddTime { get; set; }

}

View Code

传统方法如下:

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SM = context.Student.Where(A => A.StuNum == "0813091000000").FirstOrDefault();if (SM != null)

{var StudetM = newStudentModel()

{

Id=SM.Id,

StuName=SM.StuNum,

StuNum=SM.StuNum,

StuSex=SM.StuSex,

deptNum=SM.deptNum,

AddTime=SM.AddTime

};

}

}returnView();

}

}

View Code

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

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

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SM = context.Student.Where(A => A.StuNum == "0813091000000").FirstOrDefault();if (SM != null)

{

StudentModel StudentM= Mapper.DynamicMap(SM);

}

}returnView();

}

}

View Code

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

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

传统方法如下:

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SMList = context.Student.Where(A => A.StuName.Contains("陈")).ToList();if (SMList != null&&SMList.Count>0)

{foreach (var SM inSMList)

{var StudetM = newStudentModel()

{

Id=SM.Id,

StuName=SM.StuNum,

StuNum=SM.StuNum,

StuSex=SM.StuSex,

deptNum=SM.deptNum,

AddTime=SM.AddTime

};

}

}

}returnView();

}

}

View Code

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

当然,可以...

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SMList = context.Student.Where(A => A.StuName.Contains("陈")).ToList();if (SMList != null && SMList.Count > 0)

{

List StudentM = Mapper.DynamicMap>(SMList);

}

}returnView();

}

}

View Code

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

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

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

我们将StudentModel修改成如下:

afc9d142767e8c1e2d735ac00527ffa5.png

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

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

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SM = context.Student.Where(A => A.StuNum == "0813091000000").FirstOrDefault();if (SM != null)

{var StudetM = newStudentModel()

{

Id=SM.Id,

StuName=SM.StuNum,

StuNum=SM.StuNum,

StuSex=SM.StuSex,

deptNum=SM.deptNum,

AddTime=SM.AddTime,

deptName=SM.Dept.deptName

};

}

}returnView();

}

}

View Code

cf973840956e4b1e4d1037061014d038.png

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

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SM = context.Student.Where(A => A.StuNum == "0813091000000").FirstOrDefault();

AutoMapper.Mapper.CreateMap().ForMember(dest => dest.deptName, opts => opts.MapFrom(src =>src.Dept.deptName));var model = AutoMapper.Mapper.Map(SM);

}returnView();

}

}

View Code

7f5a6842e5426588499e1df2bbd6ff20.png

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

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

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

0004a24a7f66ee0f5ffe6c7b2128b41b.png

生成了2条SQL语句:

b480cc6cd3b27edd6d1e1b7b738a6c79.png

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

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

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

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{var SMList = context.Student.Include(A=>A.Dept).Where(A => A.StuName.Contains("陈")).ToList();

AutoMapper.Mapper.CreateMap()

.ForMember(dest=> dest.deptName, opts => opts.MapFrom(src =>src.Dept.deptName));var modelList = AutoMapper.Mapper.Map>(SMList);

}returnView();

}

}

View Code

2b84d1c822ddff6faf42db47677f9d10.png

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

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

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

5f94c2fecb4ccb2f76f50c965d122407.gif

50828477840f9be8f01bb82af691c7d1.gif

publicActionResult Index()

{var profiler =MiniProfiler.Current;using (profiler.Step("查询Student的数据"))

{using (BingFaTestEntities context = newBingFaTestEntities())

{

StudentModel M= newStudentModel()

{

StuName= "陈星辰",

AddTime=DateTime.Now,

deptNum= "0813092",

StuNum= "081309201",

StuSex= "男"};

Student Sm= newStudent();

AutoMapper.Mapper.CreateMap().ReverseMap();

Sm= AutoMapper.Mapper.Map(M);

context.Student.Add(Sm);

context.SaveChanges();

}returnView();

}

}

View Code

53e7c6c01bce1daba5c5d8737c13ed0e.png

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

@陈卧龙的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值