本文解釋使用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