前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用:

从安全上面考虑,领域Model都带有领域业务,让Client端引用Domain Model就意味着Client端可以绕过应用层直接完成业务逻辑的调用,这样是一种不安全的机制。

从对象传递效率上面考虑,领域Model带有业务,而这些业务一般对于UI层是没有意义的,所以带有业务的model传递起来会加重网络负担。

网上还说了DTOmodel最大的意义在于跨平台,Domain Model都是与特定的语言的数据类型有关,而这些数据类型是不能跨平台的,比如Java的类型就不能被C#使用。但在分布式模式下,Client端与Server端的平台不同是很正常的,如果Service直接返回Domain Model,Client端根本无法解析,这就要求Service返回的结果必须是标准的格式字节流。让Domain Model只使用简单类型(字符和数值)?让数据类型约束Domain Model显然不是一个好想法,所以DTO似乎是必不可少的了。

既然我们要使用DTO,那么有一件事我们就非做不可了,我们从领域层得到的是领域Model,如何把领域Model转换成只带有数据属性的DTO传递到前台呢?又或者我们从前台提交一个DTO对象,如何将DTO转换成领域Model而提交到后台呢?这个时候就需要我们的对象映射工具,目前市面上对象映射工具较多,但博主最熟悉的还是Automapper,这章就来分享下Automapper的使用。

一、AutoMapper

Automapper是一个object-object mapping(对象映射)工具,一般主要用于两个对象之间数据映射和交换。当然你也可以自己通过反射去写对象的映射,对于简单的两个属性间的数据转换,肯定没什么问题。但是如果遇到某些复杂的数据转换,比如指定某一个对象的某个属性映射到另一个对象的某一个属性,这种情况如果我们自己手动映射,恐怕就有点麻烦了吧。既然我们有现成的工具,为什么不用呢?

二、AutoMapper引用到项目中

向项目中添加AutoMapper的引用有两种方式:

1、Nuget方式

在需要使用AutoMapper的项目文件上面右键→管理Nuget程序包,打开Nuget界面,搜索Automapper,然后安装第一个即可。如下图:

2、程序包管理控制台方式

点击Visual Studio的工具菜单→程序包管理控制台,然后选择需要安装Automapper的项目(下图中的默认项目),最后在控制台里面输入命令“Install-Package AutoMapper”命令即可按照Automapper包:

三、AutoMapper使用代码示例

1、最简单的对象映射

AutoMapper使用起来还是比较简单的,最简单的用法你只需要两句话:

var oMenu = new TB_MENU() { MENU_NAME="权限管理", MENU_LEVEL="1" };

Mapper.CreateMap();

var oDto = Mapper.Map(oMenu);

首先创建映射,然后传入需要映射的对象执行映射。相信在项目中使用过AutoMapper的原因肯定也写过类似这样的AutoMapperHelper

///

/// AutoMapper帮助类

///

public static class AutoMapperHelper

{

///

/// 单个对象映射

///

public static T MapTo(this object obj)

{

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

Mapper.CreateMap(obj.GetType(), typeof(T));

return Mapper.Map(obj);

}

///

/// 集合列表类型映射

///

public static List MapToList(this IEnumerable source)

{

Mapper.CreateMap();

return Mapper.Map>(source);

}

}

当然,这是最简单的用法,稍微复杂点的用法我们在后面慢慢介绍。

2、指定字段的对象映射

前面说了,对于指定某一个对象的某个属性映射到另一个对象的某一个属性,这种场景,我们先来看看下面代码:

public partial class TB_USERS : BaseEntity

{

public string USER_ID { get; set; }

public string USER_NAME { get; set; }

public string USER_PASSWORD { get; set; }

public string FULLNAME { get; set; }

public string DEPARTMENT_ID { get; set; }

public virtual TB_DEPARTMENT TB_DEPARTMENT { get; set; }

//...后面肯定还有其他领域行为

}

public partial class TB_DEPARTMENT : BaseEntity

{

public string DEPARTMENT_ID { get; set; }

public string NAME { get; set; }

}

领域层有这两个实体model,然后我们需要得到下面的DTO_TB_USERS这一个对象

public class DTO_TB_USERS

{

[DataMember]

public string USER_ID { get; set; }

[DataMember]

public string USER_NAME { get; set; }

[DataMember]

public string USER_PASSWORD { get; set; }

[DataMember]

public string FULLNAME { get; set; }

[DataMember]

public string DEPARTMENT_ID { get; set; }

[DataMember]

public string DEPARTMENT_NAME { get; set; }

}

这个时候DTO_TB_USERS这个对象的属性分布在其他两个领域实体里面,我们看看AutoMapper如何解决:

var oDomainUser = userRepository.Entities.FirstOrDefault();

var map = Mapper.CreateMap();

map.ForMember(d => d.DEPARTMENT_NAME, opt => opt.MapFrom(x => x.TB_DEPARTMENT.NAME));

var oDto = Mapper.Map(oDomainUser);

通过上面的代码,ForMember()方法会指定哪个字段转换为哪个字段,这样就完美的将对象的层级结构由二级变成了一级(即将TB_USERS下面TB_DEPARTMENT对象的NAME值转换成了DTO_TB_USERS的DEPARTMENT_NAME值)。除此之外,Automapper里面还可以通过ForMember帮我们做其他很多我们想不到的事情,比如可以设置某个属性值保留初始值,只需要通过

map.ForMember(d => d.DEPARTMENT_NAME, opt => opt.Ignore());

这一句就帮我们搞定。

3、传递lamada的表达式映射

还记得我们在仓储里面封装了传递lamada表达式的查询方法么?试想,如果我们在Web层里面也希望传递lamada表达式去后台查询,那么这个时候就有点问题了,因为我们Web里面只能访问DTO的Model,所以只能传入DTO Model的lamada,而我们仓储里面需要传入的是领域Model的lamada,那么问题就来了,这两个lamada表达式之间必须存在一个转换关系,试想,这些东西如果让我们手动去处理,还是有难度的吧!还好,我们神奇的Automapper替我们想到了。它能够帮我们将DTO的lamada转换成领域Model的lamada,来看看代码吧:

[Import]

public IUserRepository userRepository { get; set; }

public virtual IList Find(Expression> selector)

{

//得到从Web传过来和DTOModel相关的lamaba表达式的委托

Func match = selector.Compile();

//创建映射Expression的稳妥

Func mapper = AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(Mapper.Engine).Compile();

//得到领域Model相关的lamada

Expression> lamada = ef_t => match(mapper(ef_t));

List list = userRepository.Find(lamada).ToList();

return Mapper.Map, List>(list);

}

上面方法完美实现了两种lamada之间的转换,但根据博主的使用经历,这种转换对属性的类型有很严格的要求,必须保证领域model和DTO的Model同一个属性的类型完全相同,否则容易报异常。使用的时候需要注意。

4、Automapper的其他应用

除了上面介绍的Automapper的几个简单使用,其他还有其他的一些用法。

网上很多介绍DataReader对象和实体类之间的映射:

using (IDataReader reader = db.ExecuteReader(command))

{

if (reader.Read())

{

return AutoMapper.Mapper.DynamicMap(reader);

}

}

至此,AutoMapper的常见用法基本分享完了,至于更高级的用法,有兴趣可以看看蟋蟀兄的【AutoMapper官方文档】DTO与Domin Model相互转换(上)。虽然很多高级用法在实际项目中很难用上,但多了解一点似乎也并没有坏处。

java automapper 使用_AutoMapper使用相关推荐

  1. java automapper 使用_AutoMapper实际项目运用

    AutoMapper是对象到对象的映射工具.在完成映射规则之后,AutoMapper可以将源对象转换为目标对象. 配置AutoMapper映射规则 AutoMapper是基于约定的,因此在实用映射之前 ...

  2. java automapper 使用_AutoMapper入门使用

    AutoMapper入门使用 在应用开发的过程中,首先要了解整个系统中各个系统的组件的作用,然后了解系统的工作流(workflow),最后需要梳理一遍数据流(dataflow),而在整理数据流的过程中 ...

  3. java automapper 使用_AutoMapper 使用总结

    初识AutoMapper 在开始本篇文章之前,先来思考一个问题:一个项目分多层架构,如显示层.业务逻辑层.服务层.数据访问层.层与层访问需要数据载体,也就是类.如果多层通用一个类,一则会暴露出每层的字 ...

  4. automapper java 有什么_AutoMapper简介

    先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对 ...

  5. automapper java 有什么_AutoMapper用法

    什么是AutoMapper? 在多层结构中,经常用到对象到对象的转化,手工去写复制太过麻烦.而AutoMapper就是一个可以实现自动转换的类库. 它提供了一些有趣的约定,从而弄清楚如何将类型A映射到 ...

  6. java automapper 使用_19.AutoMapper 之开放式泛型(Open Generics)

    开放式泛型(Open Generics) AutoMapper可以支持开放式泛型的映射.为开放式泛型创建映射: public class Source { public T Value { get; ...

  7. java automapper_实现AutoMapper(1.0版本)

    最近有个需求就是实体之间自动转换,网上肯定有很多现成的实现,不过还是自己写了一个,就当对java高级特性的一个熟悉的过程.这中间包含了泛型,反射,lamada表达式.对于想了解java高级特性的人来说 ...

  8. automapper java 有什么_对象映射工具AutoMapper介绍

    AutoMapper是用来解决对象之间映射转换的类库.对于我们开发人员来说,写对象之间互相转换的代码是一件极其浪费生命的事情,AutoMapper能够帮助我们节省不少时间. 一. AutoMapper ...

  9. automapper自动创建映射_AutoMapper 自动映射工具

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

最新文章

  1. 干货:Android 源码使用心得分享
  2. 【Java常识】6.0面向对象认知和Eclipse的实用使用、==号和equals方法的区别
  3. 计算机书籍-C++并发编程实战
  4. docker klee tutorial_通过Docker使用KLEE
  5. 用户体验已成过去时 AI要从公民乃至社会的角度去思考问题
  6. MySQL的分表和分区介绍
  7. 神经网络 | DeepVO:Towards End-to-End Visual Odometry
  8. 华夏银行北京分行签约第四范式智能决策平台
  9. spring中的IOC和AOP
  10. 【渝粤教育】国家开放大学2018年春季 3781-22T燃气燃烧技术与设备 参考试题
  11. python入门程序例子_Python 爬虫从入门到放弃(11 个有趣的 Python 爬虫例子)
  12. UIM28RS-IE RS485/脉冲二合一28 闭环/开环步进一体机
  13. 用HTML写手机QQ登录界面
  14. ubuntu snap 安装的nextcloud 忘记管理员密码,重新设置密码。
  15. 希尔顿康莱德酒店及度假村亮相中国科技与创新孵化中心
  16. i.MX6ULL系统移植:Linux移植6 - Linux 内核移植
  17. 徒手撸一个好玩的App:美图
  18. 宝付正式执行“适当降低小微企业支付手续费”工作部署任务
  19. 【linux常用命令】
  20. 多线程 - 三种实现

热门文章

  1. Python判断字符串是否全是数字或者字母
  2. anyRTC-语音连麦demo上线
  3. java面试题高并发,热度飙升
  4. 刘强东卸任京东CEO,互联网大厂“毕业潮”背后,it程序员该何去何从?
  5. 1885页的Python完全版电子书,从基础到爬虫、分析等高级应用,限时下载
  6. 支付宝9亿红包分钱了,你拿了多少钱?有人领到18888元吗?
  7. win10间歇性闪屏_win10系统电脑频繁闪屏刷新的解决方法
  8. Apollo:源码分析之cyber\blocker\blocker.h
  9. autoCAD不能复制粘贴解决方法
  10. 织梦搜索页是那个php,织梦dedecms仿站之搜索框、搜索页制作