dapper 调用 存储过程返回值_从0开始编写dapper核心功能、压榨性能、自己动手丰衣足食...

我偶然听说sqlsugar的性能比dapper强。对此我表示怀疑(由于我一直使用的dapper存在偏见吧),于是自己测试了sqlsugar、freesql、dapper发现他们的给我的结果是

sqlsugar>dapper>freesql(这里并不是黑那个orm,毕竟不同orm功能不同,底层实现不同,适用场景不同性能当然不同)。这让我很吃惊,dapper(号称orm king)一个执行sql的映射器,比不了基于linq语法的sqlsugar。同时也让我感到高兴,我高兴的是:orm的性能肯定还有提升的空间。

于是我便开始研究它们并着手编写。最终以一千行左右的代码量实现了dapper的基本映射功能,性能真正意义接近ado.net

对比于dapper的底层存在拆装箱操作(我的没有,请看IL),强制类型转换,dapper内置各种缓存(缓存就要考虑并发安全,就要用lock),许多功能并不是我们所需要的,一些功能又是我们迫切需要的,dapper有些定制化功能我们要查阅很多资料才能实现。浪费我们宝贵的时间,dapper对匿名类型支持并不好,这阻碍的我的另一个框架dapper.common(dapper的linq实现方案,将来要移植到sqlcommon),我让作者改一下,支持一下,作者认为linq映射也不是dapper所需要的功能,不予支持。

自己动手丰衣足食,那么我们完全可以自己编写一套。

性能测试

b053c4ac95b0048c63626a7acb549ecb.png

3b17fce51bbf285fb26e84d23c140435.png

下面进行简要实现:

完整源码地址:https://github.com/1448376744/SqlCommon

nuget也发布了v1.0.0

1.我们要如何实现?我们要实现的第一个问题是DataReader对象转实体类,用反射肯定不行。我们需要用IL来动态创建下面的函数

baba3761991d90f77cb490963ee598db.png

我们可以创建这样的函数,通过IL来动态创建,大致的过程

创建实体类型->判断实体类型中的属性在reader中是否存在->如果存在则对该字段赋值

1.我们定义一个接口,,因为匹配C#字段和数据库字段名之间有一个映射规则(是否区分大小写,是否忽略下划线等等)

9a19d49188efae0b003ff43676d71453.png

第一个接口要求我们传递一个类型的所有属性,和要绑定的列信息

第二个查找一个类型的转换方法(比如字段属性的bool,我们一个返回一个bool类型的转换函数)

第三个是用于处理匿名类型的,不细说了

第四个返回一个类型的构造器

我们编写一套实现

ead9c5a0bcc587bd180bb143fc7b4e36.png

然后实现一下DataConvertMethod(FindConvertMethod需要)这里是缩减版

f49c3761b6d2f6a9e41456e7dc4c8dc9.png

然后我们编写IL来创建动态函数,并使用用上面的接口作为参数

1ea626d8766c2f39c937caa864958507.png

c2e416c960433fc5293487feebaf79ce.png

动态创建的IL绑定函数我们需要编写一个缓存策略(我们使用hash结构进行存储),一个目标类型可能生成多个绑定函数,这根据你sql返回的字段个数和顺序有关

定义hash结构的key

7916b608d8e36ddbf04d1513474e3da2.png

d2c84936b99b2bcc3f0395ec0e5ef138.png

好了大部分工作都完成了,我们编一个sql执行器(简化版)

a035730bfb137c654cb45c731a13dbea.png

至此我们已经完成了整个流程。

我们可以发现没有拆装箱,没有强制类型转换,

对比于使用ado.net的性能差距,由于我们的动态生成绑定函数,在下次使用的时候我们需要从hash表中去查询这个函数指针。

这便是性能的差距点,而我们首先绑定函数,下次时候的时候显示的调用你定义的绑定函数。

也就是说,你只要能优化这个缓存策略,就能无限接近手写ado.net。

原文链接:https://www.cnblogs.com/chaeyeon/p/11615863.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

88f08ad1a2b5f8cdca6053c1e3138ca6.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值