在ABP中灵活使用AutoMapper
demo地址:abp.windowsservice
该文章是系列文章 基于.netcore和abp框架如何让windows服务执行quartz定时作业 的其中一篇。
automapper简介
automapper是一个简单的小型的对象映射库,是为了解决一个繁杂的问题 - 将一个对象映射到另一个对象的到处乱飞的胶水代码。这类胶水代码非常沉闷,让人怀疑自己的工作的价值性。automapper就是你摆脱此类代码的福音。
官网地址:
github地址:https://github.com/automapper/automapper
automapper的简单使用
这里拿官网的例子做一个简单说明,主要是为了引出在abp中是如何使用的,来进行对比。使用automapper将遇到的最经典的两个场景。
- 最多遇到的场景,应该是接口返回的dto和数据库entity,出于敏感信息保护或者减少接口返回数据等等的原因,dto返回的属性或者字段有所删减,也就是说需要映射的属性或者字段属性名称一致。
- dto和entity名称不一致,甚至类型不同,相互转换时甚至需要对数据有处理。
下面的例子就是字段属性基本一致。
public class order { public string ordername { get;set; } public string phonenumber { get;set; } } public class orderdto { public string ordername { get;set; } }
var config = new mapperconfiguration(cfg => cfg.createmap<order, orderdto>()); var mapper = config.createmapper(); orderdto dto = mapper.map<orderdto>(order);
或者
var config = new mapperconfiguration(cfg => cfg.createmap<order, orderdto>()); var mapper = new mapper(config); orderdto dto = mapper.map<orderdto>(order);
abp.automapper的简单使用
abp.automapper的官网文档:https://aspnetboilerplate.com/pages/documents/object-to-object-mapping
abp.automapper的nuget地址:https://www.nuget.org/packages/abp.automapper
添加nuget包
install-package abp.automapper
添加abpautomappermodule模块
[dependson(typeof(abpautomappermodule))] public class myjobcoremodule : abpmodule { }
指定映射关系
自动映射
你可以通过属性automap, automapfrom, automapto指定映射关系
改造上面的之前的例子
[automapfrom(typeof(order))] public class orderdto { public string ordername { get;set; } }
或者
[automapto(typeof(orderdto))] public class order { public string ordername { get;set; } public string phonenumber { get;set; } }
但是属性的使用场景比较窄,稍微复杂一点的场景就无法满足,比如,指定忽略一些字段,或者字段名称不同需要显示指定。
自定义映射
[dependson(typeof(abpautomappermodule))] public class myjobcoremodule : abpmodule { public override void preinitialize() { configuration.modules.abpautomapper().configurators.add(config => { config.createmap<order, orderdto>(); }); } }
忽略字段
config.createmap<order, orderdto>() .formember(u => u.phonenumber, options => options.ignore());
字段名不一致
orderdto增加手机号字段tel,映射order字段phonenumber
public class orderdto { public string ordername { get; set; } public string tel { get; set; } }
config.createmap<order, orderdto>() .formember(u => u.tel, options => options.mapfrom(input => input.phonenumber));
需要对字段进行处理后返回
比如,隐藏11位手机号的中间4位
private static string hidetel(string input) { if (string.isnullorempty(input)) { return string.empty; } var outreplace = regex.replace(input, "(\\d{3})\\d{4}(\\d{4})", "$1****$2"); return outreplace; }
config.createmap<order, orderdto>() .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.phonenumber)));
拼接映射
又比如orderdto新增邮寄地址和收货地址
namespace demo.myjob.entity.dto { public class orderdto { public string ordername { get; set; } public string tel { get; set; } public string postaladdress { get; set; } public string deliveryaddress { get; set; } } }
order的相关表orderaddress类型定义
namespace demo.myjob.entity { public class orderaddress { public string orderid { get; set; } public string postaladdress { get; set; } public string deliveryaddress { get; set; } } }
这时就需要orderaddress和order的数据相结合映射orderdto,怎么实现呢?借助元组tuple。
config.createmap<(order, orderaddress), orderdto>() .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.item1.phonenumber))) .formember(u => u.ordername, options => options.mapfrom(input => input.item1.ordername)) .formember(u => u.postaladdress, options => options.mapfrom(input => input.item2.postaladdress)) .formember(u => u.deliveryaddress, options => options.mapfrom(input => input.item2.deliveryaddress)) ;
精简配置
需要自定义的映射关系过多时,会使得preinitialize变大,不便于管理和查看。
public override void preinitialize() { configuration.modules.abpautomapper().configurators.add(config => { config.createmap<(order, orderaddress), orderdto>() .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.item1.phonenumber))) .formember(u => u.ordername, options => options.mapfrom(input => input.item1.ordername)) .formember(u => u.postaladdress, options => options.mapfrom(input => input.item2.postaladdress)) .formember(u => u.deliveryaddress, options => options.mapfrom(input => input.item2.deliveryaddress)) ; }); }
如何精简?新增类型mymapperprofile,继承automapper.profile
using system.text.regularexpressions; using automapper; using demo.myjob.entity; using demo.myjob.entity.dto; namespace demo.myjob.mapperprofiles { class mymapperprofile : profile { private static string hidetel(string input) { if (string.isnullorempty(input)) { return string.empty; } var outreplace = regex.replace(input, "(\\d{3})\\d{4}(\\d{4})", "$1****$2"); return outreplace; } public mymapperprofile() { createmap<order, orderdto>() .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.phonenumber))); createmap<(order, orderaddress), orderdto>() .formember(u => u.tel, options => options.mapfrom(input => hidetel(input.item1.phonenumber))) .formember(u => u.ordername, options => options.mapfrom(input => input.item1.ordername)) .formember(u => u.postaladdress, options => options.mapfrom(input => input.item2.postaladdress)) .formember(u => u.deliveryaddress, options => options.mapfrom(input => input.item2.deliveryaddress)) ; } } }
修改preinitialize
[dependson(typeof(abpautomappermodule))] public class myjobcoremodule : abpmodule { public override void preinitialize() { configuration.modules.abpautomapper().configurators.add(config => { config.addmaps(typeof(myjobcoremodule)); }); } }
abp.automapper版本低于4.8.0的可以修改为
config.addprofiles(typeof(myjobcoremodule));
以上就是如何在abp框架下灵活使用automapper的全部内容,谢谢阅读。
上一篇: python pandas消除空值和空格以及 Nan数据替换方法
下一篇: 隔壁小宝四岁
推荐阅读
-
在android开发中尽量不要使用中文路径的问题详解
-
在.NET中读取嵌入和使用资源文件的方法
-
在Python中操作字符串之rstrip()方法的使用
-
灵活掌握Asp.net MVC中GridView的使用方法
-
Bootstarp在pycharm中的安装及简单的使用方法
-
marginbottom在安卓中是什么意思(子元素marginBottom使用方法)
-
在Surface中IE浏览器触摸版和桌面版的设置使用技巧
-
设计模式中的迭代器模式在Cocoa Touch框架中的使用
-
在vue-cli中使用layer中的layData日期组件
-
使用jQuery快速解决input中placeholder值在ie中无法支持的问题