.net core 高性能对象映射
关于对象转换已经有不少轮子(AutoMapper,TinyMapper) .出于项目需要,手动造一个简单轮子。先贴代码
1.采用静态泛型类缓存,避免了拆箱装箱操作。
2.对于转换对象中有,字段名一样但是类型不一样的类时仍可以用
public static class Mapper<TSource, TTarget> where TSource : class where TTarget : class
{
public readonly static Func<TSource, TTarget> Map; static Mapper()
{
if (Map == null)
Map = GetMap();
} private static Func<TSource, TTarget> GetMap()
{
var sourceType = typeof(TSource);
var targetType = typeof(TTarget); var parameterExpression = Expression.Parameter(sourceType, "p");
var memberInitExpression = GetExpression(parameterExpression, sourceType, targetType); var lambda = Expression.Lambda<Func<TSource, TTarget>>(memberInitExpression, parameterExpression);
return lambda.Compile();
} /// <summary>
/// 根据转换源和目标获取表达式树
/// </summary>
/// <param name="parameterExpression">表达式参数p</param>
/// <param name="sourceType">转换源类型</param>
/// <param name="targetType">转换目标类型</param>
/// <returns></returns>
private static MemberInitExpression GetExpression(Expression parameterExpression, Type sourceType, Type targetType)
{
var memberBindings = new List<MemberBinding>();
foreach (var targetItem in targetType.GetProperties().Where(x => x.PropertyType.IsPublic && x.CanWrite))
{
var sourceItem = sourceType.GetProperty(targetItem.Name); //判断实体的读写权限
if (sourceItem == null || !sourceItem.CanRead || sourceItem.PropertyType.IsNotPublic)
continue; //标注NotMapped特性的属性忽略转换
if (sourceItem.GetCustomAttribute<NotMappedAttribute>() != null)
continue; var propertyExpression = Expression.Property(parameterExpression, sourceItem); //判断都是class 且类型不相同时
if (targetItem.PropertyType.IsClass && sourceItem.PropertyType.IsClass && targetItem.PropertyType != sourceItem.PropertyType)
{
if (targetItem.PropertyType != targetType)//防止出现自己引用自己无限递归
{
var memberInit = GetExpression(propertyExpression, sourceItem.PropertyType, targetItem.PropertyType);
memberBindings.Add(Expression.Bind(targetItem, memberInit));
continue;
}
} if (targetItem.PropertyType != sourceItem.PropertyType)
continue; memberBindings.Add(Expression.Bind(targetItem, propertyExpression));
}
return Expression.MemberInit(Expression.New(targetType), memberBindings);
}
}
3.调用方法如下
(1)构造样例类
public class A
{
public int Id { get; set; }
public string Name { get; set; }
public C User { get; set; } /// <summary>
/// 标注为notmapped特性时,不转换赋值
/// </summary>
[System.ComponentModel.DataAnnotations.Schema.NotMapped]
public D UserA { get; set; } } public class B
{
public int Id { get; set; }
public string Name { get; set; }
public D User { get; set; }
public D UserA { get; set; }
} public class C
{
public int Id { get; set; }
public string Name { get; set; }
} public class D
{
public int Id { get; set; }
public string Name { get; set; }
}
(2) 调用
var a = new A
{
Id = 1,
Name = "张三",
User = new C
{
Id = 1,
Name = "李四"
}
};
B b = Mapper<A, B>.Map(a);//得到转换结果
4.性能测试
var length = ;
var listA = new List<A>();
for (int i = ; i < length; i++)
{
listA.Add(new A
{
Id = i,
Name = "张三",
User = new C
{
Id = i,
Name = "李四"
}
});
} var sw = Stopwatch.StartNew();
for (int i = ; i < length; i++)
{
var item = listA[i];
var b = new B
{
Id = item.Id,
Name = item.Name,
User = new D
{
Id = i,
Name = "李四",
}
};
}
sw.Stop();
Console.WriteLine($"原生的时间:{sw.ElapsedMilliseconds}ms"); //表达式
Mapper<A, B>.Map(listA[]);//预先编译缓存
sw.Restart();
for (int i = ; i < length; i++)
{
Mapper<A, B>.Map(listA[i]);
}
sw.Stop();
Console.WriteLine($"表达式的时间:{sw.ElapsedMilliseconds}ms"); //AutoMapper
AutoMapper.Mapper.Initialize(cfg => cfg.CreateMap<A, B>());
sw.Restart();
for (int i = ; i < length; i++)
{
var b = AutoMapper.Mapper.Map<B>(listA[i]);
}
sw.Stop();
Console.WriteLine($"AutoMapper时间:{sw.ElapsedMilliseconds}ms"); //TinyMapper
TinyMapper.Bind<A, B>();
sw.Restart();
for (int i = ; i < length; i++)
{
var b = TinyMapper.Map<B>(listA[i]);
}
sw.Stop();
Console.WriteLine($"TinyMapper时间:{sw.ElapsedMilliseconds}ms"); Console.ReadLine();
5. 1000万数据不带子类集结果
6. 1000万数据带子类集结果
.net core 高性能对象映射的更多相关文章
- [非专业翻译] 高性能对象映射框架 - Mapster
[非专业翻译] 高性能对象映射框架 - Mapster 系列介绍 [非专业翻译] 是对没有中文文档进行翻译的系列博客,文章由机翻和译者自己理解构成,和原文相比有所有不通,但意思基本一致. 因个人能力有 ...
- C# 高性能对象映射(表达式树实现)
前言 上篇简单实现了对象映射,针对数组,集合,嵌套类并没有给出实现,这一篇继续完善细节. 开源对象映射类库映射分析 1.AutoMapper 实现原理:主要通过表达式树Api 实现对象映射 优点: . ...
- C# 高性能对象映射
1.之前在使用AutoMapper 框架感觉用着比较不够灵活,而且主要通过表达式树Api 实现对象映射 ,写着比较讨厌,当出现复杂类型和嵌套类型时性能直线下降,甚至不如序列化快. 2.针对AutoMa ...
- ASP.NET CORE 中使用AutoMapper进行对象映射
ASP.NET CORE 中使用AutoMapper进行对象映射 1.什么是AutoMapper? AutoMapper是基于对象到对象约定的映射工具,常用于(但并不仅限制于)把复杂的对象模型转为DT ...
- ASP.NET Core实现对象自动映射-AgileMapper
我们为什么要在对象之间做映射 处于耦合性或者安全性考虑或者性能考虑我们不希望将Model模型传递给他们,我们会在项目中创建一些DTO(Data transfer object数据传输对象),进行数据的 ...
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
上一篇文章(https://www.cnblogs.com/meowv/p/12961014.html)集成了定时任务处理框架Hangfire,完成了一个简单的定时任务处理解决方案. 本篇紧接着来玩一 ...
- 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十三 || DTOs 对象映射使用,项目部署Windows+Linux完整版
更新 很多小伙伴在用 IIS 发布的时候,总是会有一些问题,文章下边 #autoid-6-0-0 我也简单的动图展示了,如何 publish 到 IIS 的过程,如果你能看懂,却发现自己的项目有问题的 ...
- 关于对象映射(Dto->model) 思路的一些想法
最近粗浅的学习了下AutoMapper 这个做对象映射的第三方工具,觉得非常方便使用,所以简单的总结了一下我能想到的简单的对象映射的方式. 占时先不考虑源对象成员到目标对象成员的指定映射(即成员名不一 ...
- 一:ORM关系对象映射(Object Relational Mapping,简称ORM)
狼来的日子里! 奋发博取 10)django-ORM(创建,字段类型,字段参数) 一:ORM关系对象映射(Object Relational Mapping,简称ORM) ORM分两种: DB fir ...
随机推荐
- 系统架构设计方法论——TOGAF
https://blog.csdn.net/watermelonbig/article/details/77620847 1.ADM的架构开发阶段 ADM方法是由一组按照架构领域的架构开发顺序而排列成 ...
- Linux安装MariaDB+初始化数据库
背景说明: 在数据库中,mysql的是常用的数据库之一:作为一款开源的软件被广大公司所使用. 但是,mysql在被Oracle公司收购后,难免在以后会有取消开源的问题.所以急需一款新的数据库产品替换m ...
- mysql主从错误180301
Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ...
- Linux实战教学笔记26:http协议原理
目录 第二十六节 http协议原理 第1章 Web服务基础 1.1 http服务重要基础 1.2 HTTP协议 1.3 HTTP资源 1.4 网站流量度量术语 1.5 www服务软件介绍 1.6 本章 ...
- VUE+WebPack游戏设计:'乘法防线'游戏设计
- react native android 真机调试
http://localhost:8081/index.android.bundle?platform=android 晕死,设备掉线了 C:\Users\ZHONGZHENHUA\.android\ ...
- 前Forward / 延时Deferred
本章节描述了延时光照的渲染路径的细节,如果想了解延迟光照技术,请查阅Deferred Lighting Approaches article. Deferred Lighting is renderi ...
- Alpha混合
ShaderLab syntax: Blending 混合 Blending is used to make transparent objects. 混合是用来制作透明物体的. When graph ...
- 手把手教你生成二维码-google.zxing
一.目标 输入网址,生成网址的二维码 二.概况 1.效果:UI丑,但功能实现了 2.项目目录 三.用到的第三方资源 1.google的扫码包zxing 2.JQuery 四.步骤(用myEclipse ...
- Ubuntu的SWAP设置
1. 在Ubuntu中配置使用新创建的Swap分区 Command list: 查找Swap分区的UUID sudo blkid 在/ect/fstab中加入新的Swap分区 sudo gedit / ...