SqlDataReader的关闭问题

原文:SqlDataReader的关闭问题

昨天一个朋友使用Repeater绑定数据源时,老是出现"阅读器关闭时尝试调用 FieldCount 无效。"错误。

我看了他的代码,使用的是SqlHelper类下面的ExecuteReader方法,返回一个SqlDataReader进行绑定。


public static SqlDataReader ExecuteReader(CommandType cmdType, string cmdText, params SqlParameter[] cmdParms)
{
SqlCommand cmd = new SqlCommand();
SqlConnection conn = new SqlConnection(CONN_STRING);

// we use a try/catch here because if the method throws an exception we want to
// close the connection throw code, because no datareader will exist, hence the
// commandBehaviour.CloseConnection will not work
try
{
PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch
{
conn.Close();
throw;
}
}

然后,他自己又编写了一个类,GetData,用其中的一个方法来调用SqlHelper.


public SqlDataReader GetReader()
{
using (SqlDataReader reader = SqlHelper.ExecuteReader(CommandType.StoredProcedure, "GetAllUser", null))
{
return reader;
}

}

其中GetAllUser是一个不带参数,查询所有用户的存储过程,最后通过返回的reader进行数据源绑定。

他出现的这个错误,明显是在读取reader之前,reader已经被关闭(using的原因)。因此会读不到数据,就会报那种错误。因此,把他的调用方法改了一下:


public SqlDataReader GetReader()
{
try
{
SqlDataReader reader=SqlHelper.ExecuteReader(CommandType.StoredProcedure, "GetAllUser", null);
return reader;

}
catch (Exception)
{

return null;
}

}

这样,就不会报错了,UI层进行数据绑定也没有任何问题。但是,随之一个新的问题出现了:SqlDataReader没有手动关闭,会不会造成连接池达到最大值?

我们注意到,在SqlHelper里面,使用到了CommandBehavior.CloseConnection,这个的作用是"关闭SqlDataReader 会自动关闭Sqlconnection." 也就是说,关闭Sqlconnection是在关闭SqlDataReader的前提下进行,还是需要手动关闭SqlDataReader。又要返回SqlDataReader,又要关闭它,怎么办呢?有的网友提出:在return reader之前,先关闭reader,即进行reader.Close();

实际上这样是不行的,会报与前面一样的错误,在读取数据之前,已经被关闭。

CommandBehavior.CloseConnection用于关闭数据库连接,这是肯定的,但它会不会一起把SqlDataReader也一起关闭了呢。也就是说,用了CommandBehavior.CloseConnection,是不是就不用再手动关闭SqlDataReader了。

我们中以使用SqlHelper,然后在前台网页里面进行测试

 


protected void bind()
{

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["constr"].ToString());
conn.Open();
SqlCommand cmd = new SqlCommand("GetAllUser", conn);
SqlDataReader sdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
repeater1.DataSource = sdr;
repeater1.DataBind();
Response.Write(sdr.IsClosed.ToString()+"<br/>");
Response.Write(conn.State.ToString());

}

输出的结果是

True

Closed

说明SqlConnection和SqlDataReader都已经被关闭了。

如果把CommandBehavior.CloseConnection去掉,输出的结果则是:

False

Open

由此可见,使用了CommandBehavior.CloseConnection之后,读取完数据后,系统自动关闭了SqlDataReader和SqlConnection。听说当初微软弄出CommandBehavior.CloseConnection的目的,就是为了解决数据库的关闭问题的。

当然,我的数据量非常少,不能说明问题。希望更多的朋友说说自己的想法。

时间: 2024-08-02 22:44:25

SqlDataReader的关闭问题的相关文章

ADO.NET读书笔记系列之------SqlCommander和SqlDataReader对象

ado|command|笔记|对象 一.特点介绍 ⒈SqlCommand:表示要对SQL Server数据库执行的一个Transact-SQL语句或存储过程. ⒉SqlDataReader:提供一种从数据库读取只进的行流的一种方式.若要创建SqlDataReader,必须调用SqlCommand对象的ExecuteReader方法,而不直接使用构造函数.应该尽可能迅速的关闭SqlDataReader对象. ⒊SqlParameter:表示SqlCommand的参数,也可以是它到DataSet列的

DataReader 链接关闭解惑篇

看到有帖子:SqlDataReader的关闭问题 ,大伙对链接关闭问题看似比较迷惑,这里就给解说一下:   不管是啥xxDataReader,都是继承DataReader实现的,所以是有共性的,因此标题就以DataReader为题了.   情况一:DataReader 默认链接不关闭   示例代码: static void Main(string[] args)         {             SqlConnection con = new SqlConnection("server

阅读器关闭时 FieldCount 的尝试无效,问题解决了,但不明白原因

问题描述 兄弟我写了一返回值为SqlDataReader的方法publicSqlDataReaderGetCityList(stringProvinceID){//实例化一个数据库连接对象SqlConnectionMyConnection=newSqlConnection(ConfigurationManager.AppSettings["XXXXX"]);//实例化一个使用MyConnection打开存储过程UserLogin的数据库命令对象SqlCommandMyCommand=n

精华的微软文章.NET 数据访问架构指南

访问|架构|精华|数据|微软 数据绑定 所有这三个对象都可以作为数据绑定控件的数据源.而DataSet 和 DataTable 可作为更广范围控件的数据源.这是因为DataSet 和 DataTable 实现了(生成Ilist接口)IlistSource接口,而SqlDataReader 实现了Ienumerable接口.许多能进行数据绑定的WinForm控件需要实现了Ilist接口的数据源. 这种不同是因为为每种对象类型设计的场景类型不同.DataSet (它包含 DataTable)是一个丰

.NET 数据访问架构指南(一)

访问|架构|数据 概述:本文提供了在多层.NET应用程序中实施基于ADO.NET的数据访问层的指导原则.其重点是一组通用数据访问任务和方案,并指导你选择最合适的途径和技术(68张打印页). 目录 ADO.NET简介 管理数据库链接 错误处理 性能 通过防火墙建立链接 处理 BLOBs 事务处理 数据分页 简介 如果你在为.NET应用程序设计数据访问层,那么就应该把 Microsoft ADO.NET用作数据访问模型.ADO.NET扩展丰富,并且支持结合松散的数据访问需求.多层Web应用程序及We

ADO.NET常用对象

一.Connection对象 Connection对象也称为数据库连接对象,Connection对象的功能是负责对数据源的连接.所有Connection对象的基类都是DbConnection类. Connection对象有两个重要属性: (1)ConnectionString:表示用于打开 SQL Server 数据库的字符串: (2)State:表示 Connection 的状态,有Closed和Open两种状态. Connection对象有两个重要方法: (1)Open()方法:指示打开数据

SqlDataReader读取分页数据,pageCount你是肿么了?

自己在折腾代码的时候发现,SqlDataReader读取分页数据,存储过程中的输出参数总页数pageCount获取不准确. 我已经问过百度,技术群等..... 都说SqlDataReader用过后关闭,但是每次读取一定条数的数据,总数据并没有读完,总页数就不能获取到么? 下面把关键的代码贴出来,我相信很多小伙伴跟我遇到相同的问题,希望大牛帮忙看一下,最好能深入的讲一下,万分感谢...... 存储过程: 1 CREATE PROC Paged 2 @pageIndex INT, 3 @pageCo

用SqlDataReader返回多个结果集

using System; using System.Data; using System.Data.SqlClient; namespace Northwind { class Program { static void Main(string[] args) { SqlConnection sqlConn = null; SqlCommand sqlCmd = null; SqlDataReader sqlDR = null; try { //创建连接对象,使用集成安全方式连接,更安全 sq

阅读器关闭时 MetaData 的尝试无效。

问题描述 "/Web"应用程序中的服务器错误.--------------------------------------------------------------------------------阅读器关闭时MetaData的尝试无效.说明:执行当前Web请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息.异常详细信息:System.InvalidOperationException:阅读器关闭时MetaData的尝试无效.源错