购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP


陷阱16
不知其二
——以DataReader对象作为方法返回值的陷阱

1.陷阱产生的场景

ADO.NET中有两种数据访问的方式:一种是断开式访问(使用DataAdapter对象和DataSet对象实现数据访问),另一种是流式访问(使用Command对象和DataReader对象实现数据访问)。DataReader对象是一个轻量级的数据对象,它提供的是一种在连接数据库的状态下,只能向前的记录访问方式。如果只需要将数据读出显示,使用它是最佳选择,它的读取速度比DataSet快,占用的资源比DataSet少,所以在读取数记录时经常使用DataReader数据对象。

例4.16 以DataReader对象作为方法返回值的陷阱(光盘位置:光盘\MR\Instance\4\16\ MyDbDataReader),该实例的关键代码如下:

说明

DbDataReader是个抽象类,它是DataReader对象所对应的任何类型的基类,比如,SqlDataReader类型、OleDbDataReader类型及OracleDataReader类型等。

在上面的代码中,GetDataReader方法实现获取DataReader对象,然后在Main方法中调用该方法获取DataReader对象,最后使用while循环遍历输出所有记录的相关字段信息,编译并运行本实例,在运行过程中产生如图4.31所示的异常提示信息。

图4.31 异常提示

2.陷阱的分析

异常信息显示阅读器关闭,阅读器指的就是DataReader对象,但是程序在执行dr.Read方法之前并未直接关闭阅读器。进一步查看GetDataReader方法后发现,该方法在返回Data Reader对象之前,关闭了数据连接,如下面的代码所示:

而DataReader对象在读取数据时要求与数据库保持实时连接状态,不允许以断开连接的方式读取数据,这就是问题所在的原因。

3.陷阱的解决方法

根据上面的分析可知,要求在使用DataReader对象读取数据完成之前,不允许断开数据连接,但是也不能一直保持连接,否则会浪费宝贵的数据连接资源。另一方面,在DataReader对象读取数据完毕之后,还要关闭DataReader对象,否则会影响下一次读取数据。本实例的解决办法就是在读取数据完毕之后,关闭DataReader对象和数据连接。本实例中的Main方法不必修改,仅需要修改GetDataReader方法,修改后的代码如下:

在上面的代码中,取消了关闭数据连接的语句,但是在Main方法中也没有关闭数据连接,那么修改后的代码是如何实现关闭数据连接的呢?仔细查看上面的代码,在调用ExecuteReader方法时传入了CommandBehavior.CloseConnection参数,该参数是枚举类型,它的功能是,如果关闭关联的DataReader对象,则关联的数据连接也将关闭,这样由于在Main方法中调用了DataReader对象的Close方法,自然会关闭数据连接。 ZeyCkQuVqnP9X/tWa4FCBrQS1hL7AarAyY20EGSrRLahuemOvKgO03oD0464vFs5

点击中间区域
呼出菜单
上一章
目录
下一章
×