一、常见的将DataReader转换为List的方法
1、类似codesmith的模板生成方式
熟悉代码生成器的童鞋一定知道的。在实体类里生成了“一堆”字段,属性,数据类型等等相关的判断(不是switch...case就是if...else等等等等)。其实也就类似Herbranson原文里介绍的第一种实现方式。毫无疑问,这种方式简单直接明了,是个程序员都看得懂,但是多数人会嫌弃代码啰嗦,生成的类会显得非常臃肿庞大。
2、反射,反射,兴高采烈地登场
大家都觉得上面第一种的实现代码毫无美感,通过反射,世界就清静多了:
观察上面的代码,大家会发现程序的通用性大大增强,减少了大量重复的工作,技术含量也是杠杠的。
ps:前面两种方式的实现代码都是原文里拷贝来的。大家最常见的就是这两种方式,所以懒得写注释了,没什么难度的。
ps1:通过反射转换实体,其实还有其他写法的,但是主要思想大同小异(厚颜推荐楼猪的关于ado.net的旧文)。
二、来一点点emit,性能提高不是一点点
这就是传说已久的通过emit创建动态代理,实现实体的创建:
(1)、因为老外的这个实现方式涉及到emit的知识,大部分开发者可能了解的并不是很深入,楼猪也不是很熟悉,而且楼猪极不习惯emit这种编程风格,感觉它非常破坏代码的美感,这种牺牲色相的高级写法如果在我们的项目中大面积出现,估计大部分童鞋都会抓狂的。好在现在终于有了工具可以“Emit with a human face”了。
(2)、不管怎样,还是凭借自己学习到的一点知识储备,大胆按照自己的理解,写了点注释,对照原文作者的意思,不见得很烂,就是这么自信,呵呵。
在外部调用的方式如下(测试代码,无比丑陋,请留意):
需要说明的是,生成实体的时候,while(rdr.Read())必须判断,原文里没有提及。
三、改进ado.net快速上手里的DataReader转换成实体对象
楼猪在旧文里曾经写了个数据转换类(ModelConverter),现在放弃反射的方式,采用Herbrandson介绍的动态代理实现数据实体的创建:
DynamicBuilder类就是上面介绍的通过DynamicMethod和ILGenerator的方式。这样,QueryForList和QueryForDictionary方法的性能就得到了改善。
需要说明的是,在实体转换的时候,QueryForDictionary方法的字典的key的获取是通过BuildPrimaryKey泛型方法,直接从IDataReader里取值,而没有通过emit生成动态代理获取(有心的童鞋可以小试牛刀,看看如何通过构建动态代理获取key),个人认为使用emit适可而止,没必要矫枉过正。
先写到这里了。你还在纠结要不要学习emit? Yes,it works.
本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2010/08/01/1790057.html,如需转载请自行联系原作者