asp.net中SqlDataReader使用时关闭数据库连接的问题,转

本文解释使用SqlDataReader关闭数据库连接的问题:

例如把数据库的操作都封装到了一个类中,但SqlDataReader只有在读取完毕时才能关闭数据库,这样类中就不能关闭书库库连接。在函数中关闭,如果在函数中就关闭了会提示‘阅读器关闭时Read的尝试无效’ .

这点微软当然想到了。用着个方法dr = Cmd.ExecuteReader(CommandBehavior.CloseConnection);,MSDN中对 CommandBehavior.CloseConnection的解释是‘在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。’

但。。。。。,请看下面的问题:

在函数中执行操作然后返回DataReader,然后在外面读出数据,读取完毕后在外部关闭DataReader,这样函数中的Connetion会自动关闭吗?

实例展示:

我把所有对数据库的操作都封装到了一个类中,写程序时就直接调用这个类的某个函数来返回结果!(我们学习网-weareleran.net)


下面是一个用来返回DataReader对象的通用类,
public SqlDataReader GetReader(string SQL)
{
SqlConnection Conn;
Conn = new SqlConnection(strConn);
Conn.Open();
SqlCommand Cmd ;
Cmd = CreateCmd(SQL, Conn);
SqlDataReader dr;
try
{
dr = Cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch
{
throw new Exception(SQL);
}
Cmd.Dispose();
return dr;
}

在程序在需要的时候我就直接构造好SQL语句,调用这个函数即可,如下:

string     sql="select     *     form     student";     

SqlDataReader dr = mydate.GetReader(sql);//调用数据库操作通用类中的GetReader函数,返回SqlDataReader

if(dr.Read())
{
.........读出数据,赋值给页面控件.....
}
dr.Close();//操作完毕,关闭DataReader

我按照这样的写基本已经没问题了,可以正常读取出数据,但是我现在担心的一个问题是Connection对象的关闭问题,因为是在函数中建立的 Connection对象,没办法在外部来关闭它,又不能在函数中关闭,如果在函数中就关闭了会提示‘阅读器关闭时Read的尝试无效’

但我在函数中就用了这一行:dr = Cmd.ExecuteReader(CommandBehavior.CloseConnection);,MSDN中对 CommandBehavior.CloseConnection的解释是‘在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。’

也就是说我在关闭了DataReader之后,关联的Connection会自动关闭,我也测试过,测试代码如下:

string     strConn     =     ConfigurationSettings.AppSettings["SqlDatabase"];     
SqlConnection cn=new SqlConnection(strConn);
cn.Open();
string sql="select * form student";
SqlCommand cm=new SqlCommand(sql,cn);
SqlDataReader dr=cm.ExecuteReader(CommandBehavior.CloseConnection);
SqlDataReader dr = mydate.RunProcGetReader(sql);
if(dr.Read())
{
.......读取数据
}
dr.Close();//关闭DataReader
Response.Write(cn.State);//输出Connetion的状态

结果运行这一段,输出:Closed ,可见Connetion确实自动关闭了!但是如我在上面所说,我的Coonection是在函数在建立的,在函数中执行操作然后返回 DataReader,然后在外面读出数据,读取完毕后在外部关闭DataReader,这样函数中的Connetion会自动关闭吗

我把所有对数据库的操作都封装到了一个类中,写程序时就直接调用这个类的某个函数来返回结果!

下面是一个用来返回DataReader对象的通用类,

public     SqlDataReader     GetReader(string     SQL)       
{
SqlConnection Conn;
Conn = new SqlConnection(strConn);
Conn.Open();
SqlCommand Cmd ;
Cmd = CreateCmd(SQL, Conn);
SqlDataReader dr;
try
{
dr = Cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch
{
throw new Exception(SQL);
}
Cmd.Dispose();
return dr;
}


在程序在需要的时候我就直接构造好SQL语句,调用这个函数即可,如下:

string sql="select * form student";

SqlDataReader dr = mydate.GetReader(sql);//调用数据库操作通用类中的GetReader函数,返回SqlDataReader

if(dr.Read())

{

.........读出数据,赋值给页面控件.....

}

dr.Close();//操作完毕,关闭DataReader

我按照这样的写基本已经没问题了,可以正常读取出数据,但是我现在担心的一个问题是Connection对象的关闭问题,因为是在函数中建立的 Connection对象,没办法在外部来关闭它,又不能在函数中关闭,如果在函数中就关闭了会提示‘阅读器关闭时Read的尝试无效’

但我在函数中就用了这一行:dr = Cmd.ExecuteReader(CommandBehavior.CloseConnection);,MSDN中对 CommandBehavior.CloseConnection的解释是‘在执行该命令时,如果关闭关联的 DataReader 对象,则关联的 Connection 对象也将关闭。’

也就是说我在关闭了DataReader之后,关联的Connection会自动关闭,我也测试过,测试代码如下:

string     strConn     =     ConfigurationSettings.AppSettings["SqlDatabase"];     
SqlConnection cn=new SqlConnection(strConn);
cn.Open();
string sql="select * form student";
SqlCommand cm=new SqlCommand(sql,cn);
SqlDataReader dr=cm.ExecuteReader(CommandBehavior.CloseConnection);
SqlDataReader dr = mydate.RunProcGetReader(sql);
if(dr.Read())
{
.......读取数据
}
dr.Close();//关闭DataReader
Response.Write(cn.State);//输出Connetion的状态

结果运行这一段,输出:Closed ,可见Connetion确实自动关闭了!但是如我在上面所说,我的Coonection是在函数在建立的,在函数中执行操作然后返回 DataReader,然后在外面读出数据,读取完毕后在外部关闭DataReader,这样函数中的Connetion会自动关闭吗?

自己做了个测试:(我们学习网-www.wearelearn.net)


public SqlConnection conn;
protected void Page_Load(object sender, EventArgs e)
{
conn = new SqlConnection(DAL.SQLHelper.conn_String);
show();
}
//简单的封装方法
protected static SqlDataReader reDatareader(SqlConnection conn)
{
SqlCommand cmd = new SqlCommand("select top 10 * from article ", conn );
conn.Open();
SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}
//应用封装方法
protected SqlDataReader redr()
{
SqlDataReader dr = reDatareader(conn);
return dr;
}
//调用类,模拟3层构架。
protected void show()
{
SqlDataReader dr = redr();
if (dr.HasRows)
{
while (dr.Read())
{
}
Response.Write(conn.State.ToString());
dr.Dispose();
Response.Write(conn.State.ToString());
}
}

结果输出 OpenClosed,呵呵,结果能关闭。

来自:http://hi.baidu.com/westfruit/blog/item/6ed56f1911927b4f43a9ad87.html