详谈ASP.NET的DataReader对象
最近频繁用到了DataReader这个对象,其实对于DataReader,之前也用到过,说实话我个人觉得很不好懂。相比之下觉得DataSet对象好用的多,但是有时取出的数据不需要很多的时候,DataReader还是很有用的。
在此就对DataReader进行一下解释,这也是个人对DataReader的理解,难免会有错误,大家互相学习下。有理解上的错误也希望大家能过指正出来,帮助我更好的理解,谢谢。
首先DataReader相比于DataSet,DataReader是一个抽象类,所以不能用
DataReader DR = new DataReader(),来构造函数创建对象,如果要创建一个DataReader对象,必须通过command对象的ExecuteReader方法。
其次,DataReader对象访问数据的方式,只能顺序读取数据,而且不能写入数据(这点DataSet占据绝对的优势),所谓的顺序读取数据是将数据表中的行从头至尾一次读出。DataReader被创建时,纪录指针在表的最前端,可以使用Read方法每次从表中读取一条纪录。
总的来说DataSet存的是二维数组,而DataReader存的是一维数组。而且DataSet采用的是非连接的传输模式访问数据源,一旦用户所请求的数据读入DataSet,与数据库的连接就关闭,而DataReader则要时刻保持与数据库连接状态。
就我来说,重要的和常用的属性和方法:
FieldCount属性 获取DataReader对象所包含的纪录行数
Close() 关闭DataReader对象
其实有各种GetBoolean(col),GetChar(col),GetString(col),GetDateTime(col),GetInt32()等等获取序号为col的列的值,而这些基本上可以被GetValue(col)方法所取代。
GetValue(col) 获取序号为col的列的值
GetValues(values) 获取所有字段的值,并将字段值存放到values数组中
GetValues(values)方法原来我不会用,特别是对于这个values数组是哪里来的,以及如果自定义该定义为什么类型呢,后来百度就知道了,用这个方法之前,Object[] values = new Object[sqlrd.FieldCount];这个是定义values数组的方法前提。
Read() 读取下一条纪录,返回布尔型,返回true,则表示有下一条纪录。一般这个方法与while()循环一起用。是DataReader对象最重要的一个方法。
其他的无关痛痒的方法:(我觉得这个在提取数据的时候,不知道具体的数据类型,用来查看数据的数据类型的作用居多,或者用来查找问题调试吧。反正我一般用不到这些个方法)
GetDataTypeName(col) 获取序号为col的列的来源数据类型名
GetFieldType(col) 获取序号为col的列的数据类型,一般显示会是System.**
GetName(col) 获取序号为col的列的字段名
GetOrdinal(name) 获取字段名为name的列的序号
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
protected void Page_Load(object sender, EventArgs e) { string price = Request.QueryString[ "价格" ]; string con = ConfigurationManager.ConnectionStrings[ "con" ].ToString(); SqlConnection sqlcon = new SqlConnection(con); string sql = "select * from Cloths where 价格 = '" + price + "'" ; //string sql = "select * from Cloths"; sqlcon.Open(); SqlCommand sqlcom = new SqlCommand(sql, sqlcon); SqlDataReader sqlrd; sqlrd = sqlcom.ExecuteReader(); Response.Write( "获取DataReader对象包含的记录行数,注意这里DataReader的结构跟数据库的结构是不一样的,它把数据库的一行转换成了一列:" + sqlrd.FieldCount); Response.Write( "<br>" ); Response.Write( "获取序号为0的列的来源数据类型名:" + sqlrd.GetDataTypeName( 0 )); Response.Write( "<br>" ); Response.Write( "获取序号为0的列的数据类型:" + sqlrd.GetFieldType( 0 )); Response.Write( "<br>" ); Response.Write( "获取序列号为0的列的字段名:" +sqlrd.GetName( 0 )); Response.Write( "<br>" ); Response.Write( "获取字段名为品牌的列的序号:" +sqlrd.GetOrdinal( "品牌" )); Response.Write( "<br>" ); while (sqlrd.Read()) { Response.Write( "<br>" ); Response.Write(sqlrd[ "id" ] + "," + sqlrd[ "品牌" ] + "," + sqlrd[ "价格" ] + "," + sqlrd[ "数量" ]); Response.Write( "<br>" ); Response.Write( "<br>" ); Response.Write( "下面的显示要注意,为什么序列号为0的是品牌而不是id,虽然GridViewCommon页面第一列是id,不过这里是要充分尊重数据库的结构,可以看出数据库中第一列是品牌!" ); Response.Write( "<br>" ); Response.Write( "这里通过GetString函数取出序号为0的列的数据,这里要根据数据的不同类型选用不同的Get函数,可能是GetChar(),GetInt32()等等:" +sqlrd.GetString( 0 )); //这里可以看出GetValue函数可以不需要事先知道每一列的数据类型就可以取出数据,所以尽量用GetValue函数 Response.Write( "<br>" ); Response.Write( "这里通过GetValue函数取出序号为0的列的数据,不需要管数据时什么类型,这里注意跟上面的比较:" + sqlrd.GetValue( 0 )); Response.Write( "<br>" ); Response.Write( "<br>" ); Response.Write( "这里是运用GetValue()的方法提取显示数据的:" ); for ( int i = 0 ; i < sqlrd.FieldCount;i++ ) //这里通过循环取出数据,其实就是循环使用GetValue()方法 { Response.Write(sqlrd.GetValue(i)); //这个是一步一步取数据,用的是GetValue()方法,相比于GetValues,GetValues是一步到位,只要循环数组就好 Response.Write( "<br>" ); } Response.Write( "<br>" ); Response.Write( "这里是运用GetVales()方法提取显示数据的:" ); Response.Write( "<br>" ); Object[] values = new Object[sqlrd.FieldCount]; //这一步是很重要的,你要先给定义一个数组 sqlrd.GetValues(values); //注意这边是用的是GetValues(values)方法 Response.Write(values[ 0 ]+ "," +values[ 1 ]+ "," +values[ 2 ]+ "," +values[ 3 ]+ "," +values[ 4 ]); Response.Write( "<br>" ); for ( int i = 0 ; i < sqlrd.FieldCount;i++ ) //这里是循环的values数组,而不是GetValues(values)方法 { Response.Write( "<br>" ); Response.Write(values[i]); Response.Write( "<br>" ); } } sqlrd.Close(); Response.Write( "<br>" ); Response.Write(sqlrd.RecordsAffected); //获取执行SQL语句所更改,插入或删除的行数 sqlcon.Close(); } |
这是对应的Cloths数据库的设计和内容:
这个是效果图:
可能有同学对于代码中的string price = Request.QueryString["价格"]有疑惑,其实这个我叫做超链接传值或者页面间传值吧,这个应该不妨碍大家的阅读和理解,它对应的传值过来的页面我就不传上来了,因为联系不大,就一个传值罢了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· Open-Sora 2.0 重磅开源!
2013-11-23 双十一怎么那么强?淘宝自主研发的文件系统大揭秘!
2013-11-23 JQuery的选择器对控件ID含有特殊字符的解决方法-涨姿势了!
2010-11-23 某些博文的缺点