欢迎来到天天文库
浏览记录
ID:62154250
大小:36.20 KB
页数:14页
时间:2021-04-19
《从IDataReader中读取数据实体.docx》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、从IDataReader中读取数据实体 现在ORM已经是一门非常成熟的技术了,相信用的人不少,加上Linqtosql和EntityFramework的推波助澜,现在还用DataSet和DataTable的人已经越来越少了,不过,如果项目里面不用ORM工具,就不得不回归到DataSet时代吗? 也许,我们没法改变项目的决策,但是,我们可以自己制造工具。 这里先忽略掉那些麻烦的sql,调用那个存储过程之类的事情,假设我们已经通过各种手段(不管你是SqlHelper的拥护者还是enterpriselibrary的支持者,或者是自己动手丰衣足食的DIY派),得到了一个IDataReader
2、实例(什么,你不知道IDataReader接口?去msdn看看吧),并且把msdn上的说明: 提供一种方法来读取一个或多个通过在数据源执行命令所获得的只进结果集流 简化成: 提供一种方法来读取一个通过在数据源执行命令所获得的只进结果集流 也就是说,忽略掉一个存储过程返回多个结果集的情况下,我们可以直接把这个IDataReader实例中承载的数据转换为一个List的形式。 读到这里你可能会觉得这样的功能用一个反射就可以搞定了,何必写这么一篇水文? 不过,这里用的不是常规反射。什么意思?反射还有常规和非常规之分吗? 常规的反射是直接使用GetProperty和SetV
3、alue就可以实现这样的功能了,但是常规反射的问题是反射的效率问题,这样的代码效率是手写代码的1/1000,也就是说,虽然你写的很轻松,但是对CLR来说,这个代码执行的非常累。 我这里要用的是反射中的Emit技术,动态拼装IL,获得一个高性能转换器,其执行效率至少是手写代码1/2,也就是说,使用这个代码的目的是你写的轻松,CLR执行的也轻松。 不过,在这个之前,需要先定义数据实体,这个又是每个人的习惯都不一样的东西,我个人是习惯于利用Attribute来表明哪个属性是哪一列,不过考虑到便捷性,会用一个类级的Attribute表明这个类默认为是数据列,或者表明不是默认为是数据列: 1
4、 [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] 2 internal sealed class DbResultAttribute : Attribute 3 { 4 5 public DbResultAttribute() 6 : this(true) { } 7 8 public DbResultAttribute(bool defaultAsDbColumn) 9 {1
5、0 DefaultAsDbColumn = defaultAsDbColumn;11 }12 13 public bool DefaultAsDbColumn { get; private set; }14 15 }16 复制代码 而对于普通的属性,再给与一次修改列名和排除在数据列之外的机会: 1 [AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 2 internal sealed cla
6、ss DbColumnAttribute : Attribute 3 { 4 5 public DbColumnAttribute() { } 6 7 public string ColumnName { get; set; } 8 9 public bool Ignore { get; set; }10 11 }12 复制代码 这样,我们就可以很简单的定义一个数据实体了: 1 [DbResult] 2 public class MyClass 3 { 4 public int
7、 IntValue { get; set; } 5 public string StringValue { get; set; } 6 [DbColumn(ColumnName = "DecimalValue")] 7 public decimal? NullableDecimalAndDifferentName { get; set; } 8 public MyEnu
此文档下载收益归作者所有