Mapper 实体转换Entiy to Dto
实际使用中发现很多问题 如果用EFcore 框架,这个表达式树生成一个新的实体
导致EFcore 跟踪失败!
/// <summary>
/// 生成表达式目录树 泛型缓存
/// </summary>
/// <typeparam name="TIn"></typeparam>
/// <typeparam name="TOut"></typeparam>
public class ExpressionGenericMapper<TIn, TOut>//Mapper`2
{
private static Func<TIn, TOut> _FUNC = null;
private static Func<TIn, TOut, TOut> _FUNC2 = null;
public static TOut Trans(TIn t)
{
return _FUNC(t);
} /// <summary>
/// 批量实体转换
/// </summary>
/// <param name="list">被转换的实体List</param>
/// <returns></returns>
public static List<TOut> TransList(List<TIn> list)
{
List<TOut> outs = new List<TOut>();
foreach (var item in list)
{
outs.Add(Trans(item));
}
return outs;
} /// <summary>
/// 把TOut 按照TIn来更新
/// </summary>
/// <param name="news"></param>
/// <param name="old"></param>
/// <returns></returns>
public static TOut Modify(TIn news, TOut old)
{
return _FUNC2(news, old);
} static ExpressionGenericMapper()
{
Type stringType = typeof(string);
#region 创建构造对象的委托
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(TIn), "m");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
foreach (var item in typeof(TOut).GetProperties())
{
var type = typeof(TIn);
if (item.PropertyType.IsClass && item.PropertyType != stringType)//排除String以外的引用类型,不进行赋值
{
continue;
}
var prop = type.GetProperty(item.GetMappingName());//从Out类找映射的字段名
if (prop != null)//如果TIn里能找到该属性
{ MemberExpression property = Expression.Property(parameterExpression, prop);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
}
foreach (var item in typeof(TOut).GetFields())
{
var type = typeof(TIn);
if (item.FieldType.IsClass && item.FieldType != stringType)//排除String以外的引用类型,不进行赋值
{
continue;
}
var prop = type.GetField(item.GetMappingName());//从Out类找映射的字段名
if (prop != null)
{
MemberExpression property = Expression.Field(parameterExpression, prop);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
} }
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
Expression<Func<TIn, TOut>> lambda = Expression.Lambda<Func<TIn, TOut>>(memberInitExpression, new ParameterExpression[]
{
parameterExpression
});
_FUNC = lambda.Compile();//拼装是一次性的
}
#endregion
#region 修改对象的委托
{ ParameterExpression oExpression = Expression.Parameter(typeof(TOut), "o");
ParameterExpression nExpression = Expression.Parameter(typeof(TIn), "n");
List<MemberBinding> memberBindingList = new List<MemberBinding>();
foreach (var item in typeof(TOut).GetProperties())
{
var type = typeof(TIn);
if (item.PropertyType.IsClass && item.PropertyType != stringType)//排除String以外的引用类型,不进行赋值
{
continue;
}
var prop = type.GetProperty(item.GetMappingName());
if (prop != null)
{
MemberExpression property = Expression.Property(nExpression, prop);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
else
{
var propOld = typeof(TOut).GetProperty(item.Name);
MemberExpression property = Expression.Property(oExpression, propOld);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
}
foreach (var item in typeof(TOut).GetFields())
{
var type = typeof(TIn);
if (item.FieldType.IsClass && item.FieldType != stringType)//排除String以外的引用类型,不进行赋值
{
continue;
}
var prop = type.GetField(item.GetMappingName());
if (prop != null)
{
MemberExpression property = Expression.Field(nExpression, prop);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
else
{
var propOld = typeof(TOut).GetField(item.Name);
MemberExpression property = Expression.Field(oExpression, propOld);
MemberBinding memberBinding = Expression.Bind(item, property);
memberBindingList.Add(memberBinding);
}
}
MemberInitExpression memberInitExpression = Expression.MemberInit(Expression.New(typeof(TOut)), memberBindingList.ToArray());
Expression<Func<TIn, TOut, TOut>> lambda = Expression.Lambda<Func<TIn, TOut, TOut>>(memberInitExpression, new ParameterExpression[]
{
nExpression, oExpression
});
_FUNC2 = lambda.Compile();//拼装是一次性的
}
#endregion
} } public static class ExpressionGenericMapperExtend
{
public static string GetMappingName(this PropertyInfo prop)
{ if (prop.IsDefined(typeof(MappingAttribute), true))
{
MappingAttribute display = prop.GetCustomAttribute(typeof(MappingAttribute)) as MappingAttribute;
return display.MappingName;
}
return prop.Name; } public static string GetMappingName(this FieldInfo prop)
{ if (prop.IsDefined(typeof(MappingAttribute), true))
{
MappingAttribute display = prop.GetCustomAttribute(typeof(MappingAttribute)) as MappingAttribute;
return display.MappingName;
}
return prop.Name; }
} [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class MappingAttribute : Attribute
{
public string MappingName;
public MappingAttribute(string _MappingName)
{
this.MappingName = _MappingName;
} }
Mapper 实体转换Entiy to Dto的更多相关文章
- mapstruct 实体转换及List转换,@Mapper注解转换
本文参考 https://blog.csdn.net/u012373815/article/details/88367456 主要是为了自己使用方便查询. 这些都是我平时用到了,大家有什么好方法或者有 ...
- 【道德经】漫谈实体、对象、DTO及AutoMapper的使用
写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...
- .Net Core2.2 使用 AutoMapper进行实体转换
一.遇到的问题 在. Core Api 的编写中,我们经常会对一些功能点进行新增编辑操作,同时我们有时也会进行查询,但是我们查询的表的数据与我们返回的数据相差甚大,这是我们有需要自己手动进行类型的转换 ...
- DataTable转List<Model>通用类【实体转换辅助类】
/// <summary> /// DataTable转List<Model>通用类[实体转换辅助类] /// </summary> public class Mo ...
- HBaseConvetorUtil 实体转换工具
HBaseConvetorUtil 实体转换工具类 public class HBaseConvetorUtil { /** * @Title: convetor * @De ...
- 当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出?
当实体类中entity/DTO/VO等类中,有枚举值,应该怎么输出? 问题: orderStatus 和 payStatus都是枚举类,并且枚举的个数达地10来个,我们不可能在模板页面(jsp/ftl ...
- Datatable转实体 实体转换辅助类
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.R ...
- html实体转换
摘要: 在 HTML 中,某些字符是预留的.在 HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签.如果希望正确地显示预留字符,我们必须在 HTML 源代码中 ...
- C# 获取config文件 实体转换
随着项目的扩展,单独的key,value配置文件已经不能满足需求了 这里需要自定义配置节点,例如 <!--自定义 具体实体类配置问节点信息--> <School Name=" ...
随机推荐
- 在阿里云Centos7.6上面部署基于Redis的分布式爬虫Scrapy-Redis
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_83 Scrapy是一个比较好用的Python爬虫框架,你只需要编写几个组件就可以实现网页数据的爬取.但是当我们要爬取的页面非常多的 ...
- React报错之No duplicate props allowed
正文从这开始~ 总览 当我们为相同的组件传递相同的属性多次时,就会导致"No duplicate props allowed"警告.为了解决该警告,请确保只传递一次该属性.比如说, ...
- 关于linux的一点好奇心(四):tail -f文件跟踪实现
关于文件跟踪,我们有很多的实际场景,比如查看某个系统日志的输出,当有变化时立即体现,以便进行问题排查:比如查看文件结尾的内容是啥,总之是刚需了. 1. 自己实现的文件跟踪 我们平时做功能开发时,也会遇 ...
- Host long.com not found: 2(SERVFAIL)
环境: centos 7.9 地址:192.168.200.100 相关配置 name.conf文件: named.zones文件: 正反解析文件: 重启DNS服务: 1 [root@server ...
- 虚拟DOM解析及其在框架里的应用
虚拟DOM解析及其在框架里的应用 浏览器是怎样解析HTML并且绘出整个页面的 上图为webkit引擎浏览器的处理流程,如上图大致分为4大步: 第一步,HTML解析器分析html,构建一颗DOM树: 第 ...
- ubantu安装中文失败的改正方法
情况说明 一开始我也是像博主们那样安装,但是一直在这个界面安装失败,太悲伤了!! 报错内容 c Failed to fetch http://us.archive.ubuntu.com/ubuntu/ ...
- mybatisplus-ActiveRecord 模式
ActiveRecord 模式 直接调用Model对象来进行增删改查. 实体类只需继承 Model 类即可进行强大的 CRUD 操作 需要项目中已注入对应实体的BaseMapper 实体类User 点 ...
- RabbitMQ 入门系列:9、扩展内容:死信队列:真不适合当延时队列。
系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...
- 如何将原生微信小程序页面改成原生VUE框架的H5页面
项目背景: 公司为了实现小程序与H5页面共同覆盖,全面推广.特此想将已有的小程序进行快速改造上线(二周内),研发出H5版本.目前公司前端技术较为薄弱,现有的技术解决方案还停留在JSP. 问题: 如何将 ...
- 日志:Redo Log 和 Undo Log
本篇文章主要介绍 Redo Log 和 Undo Log: 利用 Redo Log 和 Undo Log 实现本地事务的原子性.持久性 Redo Log 的写回策略 Redo Log Buffer 的 ...