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=" ...
随机推荐
- 中高级Java程序员,挑战20k+,知识点汇总(一),Java修饰符
1 前言 工作久了就会发现,基础知识忘得差不多了.为了复习下基础的知识,同时为以后找工作做准备,这里简单总结一些常见的可能会被问到的问题. 2 自我介绍 自己根据实际情况发挥就行 3 Java SE ...
- Nginx listen、server_name、location的配置
# Nginx静态资源的配置指令 # listen指令 # 语法 listen address[:port][default_server] # 如: listen 127.0.0.1:8000: # ...
- LuoguP1725 琪露诺 (动态规划)
\(单调队列\) 或 \(堆\) 优化 #include <iostream> #include <cstdio> #include <cstring> #incl ...
- es5 es6 新增
es5的新特性 对于数组和字符串都进行了加强 map 遍历 es6的新特性 数组的增强 find 查找findIndex 查找下标 字符的增强 includes 是否包含 (包含返回true 不包含返 ...
- JavaScript(上)
说说你对作用域链的理解 作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到 window 对象即被终止,作用域链向下访问变量是不被允许的. 简单的说,作 ...
- Markdown使用指南
1. Markdown是什么? Markdown是一种轻量级标记语言,它以纯文本形式(易读.易写.易更改)编写文档,并最终以HTML格式发布. Markdown也可以理解为将以MARKDOWN语法编写 ...
- Think PHP框架基础安装6.0
第一步:点击基础安装tp框架composer create-project topthink/think tp 第二步:点击架构多应用模式 拓展composer require topthink/th ...
- Databend 源码阅读系列(二):Query server 启动,Session 管理及请求处理
query 启动入口 Databend-query server 的启动入口在 databend/src/binaries/query/main.rs 下,在初始化配置之后,它会创建一个 Global ...
- .md图片链接转存并替换路径,及相关报错解决方法
最初我想把Typora中.md文件中的web图片链接都下载保存到本地,并且替换.md文本中的路径 说干就干,因为在网上没有找到现成的程序所以自己写了这个程序 思路是循环查找文件夹中的文件,然后yiel ...
- centos7使用tar包安装mysql5.7
特别注意: 文档中涉及到密码的都是用的是弱密码,是存在安全风险的,一定要根据自己的情况修改为复杂度更高的密码! centos 7.6 mysql 5.7.31 基础目录: /srv/{app,data ...