.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 ...
随机推荐
- SqlServer数据压缩测试
SqlServer数据压缩测试 环境说明 操作系统:WIN SERVER 2012 R2 Standard 数据库系统: SQLSERVER 2016 SP1 Enterprise Evaluatio ...
- postgresql 相关
http://www.yiibai.com/html/postgresql/2013/080998.html 1.安装PG的client以及函数库: yum install postgresql ...
- shell 脚本的坑
最近都在写shell脚本,免不了遇到每个新手都要填的坑,在这里简单记录一下. test语句的坑 test语句在shell脚本里用的非常多,像if语句后面的其实都是test语句,也是新手最容易遇到坑的地 ...
- java算法 第七届 蓝桥杯B组(题+答案) 6.方格填数
6.方格填数 (结果填空) 如下的10个格子 (如果显示有问题,也可以参看[图1.jpg]) 填入0~9的数字.要求:连续的两个数字不能相邻.(左右.上下.对角都算相邻) 一共有多少种可能的填数方案 ...
- Java基础知识常识总结
Java基础知识常识总结 1.面向对象的特征以及对他的理解? 封装,继承,多态,如果再增加一条就是抽象. 2.Object有几种方法,分别是什么? 在JDK1.5中的11种方法,分别有: toStri ...
- Mysql配置文件详解 my.cof
Mysql配置文件详解 # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/5.6/ ...
- 关于fastjson的一些知识
今天被问到了一些有关fastjson的知识,问了fastjson内部的实现机制,笔者只是用过fastjson这个包,还真没了解过它的机制等. 下去后搜索了一些有关fastjson的知识,希望能对自己和 ...
- SQLSERVER中常用的系统视图
QLServer中提供了相当丰富的系统视图,能够从宏观到微观,从静态到动态反应数据库对象的存储结果.系统性能.系统等待事件等等.同时 也保留了与早期版本兼容性的视图,主要差别在于SQLServer20 ...
- crontab定期执行shell脚本
[场景]: 需要定期运行Hadoop的MapReduce [解决办法]: 编写一个运行MapReduce的Shell脚本.然后使用crontab配置定时任务. [Shell脚本] #!/usr/bin ...
- 谈谈Spring 注入properties文件总结
本篇谈谈Spring 注入properties文件总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 spring提供了多种方式来注入properties文件,本文做一个 ...