码农奇迹
专注、专业、无畏的前行
 这两天在对照几个典型的.net网站的时候,发现了一个小小的问题,大家在对数据库操作的时候经常会用到SqlDataReader,这个方法在调用完之后是要及时关闭的,问题就是什么时候关闭是合适的?

为了这个问题我专门上微软的官方论坛找了点东西,我在这里和我平时用的稍微的对比了一下

我们平时用方法一般是(至少我以前看到的是的,特别是很多.net书籍上):

 

/// <summary>
/// 常见的获取SqlDataReader方法
/// 通常的数据访问层都会提供这个方法
/// </summary>
static SqlDataReader GetReader()
{
    
//通过连接字符串获取连接
    SqlConnection con = new SqlConnection(conn_String);
    
try
    {
        
//打开连接,执行查询
        
//并且返回SqlDataReader
        con.Open();
        SqlCommand cmd 
= con.CreateCommand();
        cmd.CommandText 
= Sql;
        SqlDataReader dr 
= cmd.ExecuteReader();
        
return dr;
    }
    
finally
    {
        
//这里的代码就是问题所在
        
//如果这里执行关闭:

        con.Close();

        
//那返回的SqlDataReader将毫无用处,因为其
        
//依赖的连接已经关闭
        
//如果这里不执行con.Close();那返回后该连接将永远无法关闭,因为调用方无法
        
//得到连接对象
    }
}

我在微软的官方实例petshop中看的方法却是:

 static SqlDataReader GetReader_CloseConnection(SqlConnection con)
    {
        
try
        {
            
//打开连接,执行查询
            
//并且返回SqlDataReader
            con.Open();
            SqlCommand cmd 
= con.CreateCommand();
            cmd.CommandText 
= Sql;
            SqlDataReader dr 
= cmd.ExecuteReader(CommandBehavior.CloseConnection);
            
return dr;
        }
        
finally
        {
            
//不需要使用con.Close();
        }
    }

我找了找CommandBehavior.CloseConnection的作用

CommandBehavior.CloseConnection的功能恰好就是为了避免类似的尴尬境地,它能够保证当SqlDataReader对象被关闭时,其依赖的连接也会被自动关闭。

只需要在使用DataReader对象之后的时候,将DataReader对象关闭即可,这样conn就自己关闭了。找了个小例子:

 

/// <summary>
/// 测试方法
/// </summary>
static void Main(string[] args)
{
    
//建立连接
    SqlConnection con = new SqlConnection(conn_String);
    
try
    {
        
//测试使用了CommandBehavior.CloseConnection的方法
        Console.WriteLine("测试使用了CommandBehavior.CloseConnection的方法:");
        SqlDataReader sdr 
= GetReader_CloseConnection(con);
        
while (sdr.Read()) { }
        sdr.Close();
        Console.WriteLine(
"读取完毕后的连接状态:" + con.State.ToString());
        
//测试没有使用CommandBehavior.CloseConnection的方法
        Console.WriteLine("测试没有使用CommandBehavior.CloseConnection的方法:");
        SqlDataReader sdr1 
= GetReader_NoCloseConnection(con);
        
while (sdr1.Read()) { }
        sdr1.Close();
        Console.WriteLine(
"读取完毕后的连接状态:" +
        con.State.ToString());
        Console.Read();
    }
    
finally
    {
        
//确保连接被关闭
        if (con.State != ConnectionState.Closed)
            con.Close();
    }
}

读取完毕后的连接状态:Closed

测试没有使用CommandBehavior.CloseConnection的方法:

读取完毕后的连接状态:Open

正如读者所看到的,使用了CommandBehavior.CloseConnection得到的SqlDataReader对象,在关闭的同时会自动地关闭其依赖的数据库连接对象,这个特性解决了数据访问层编写中的困境。

转自:http://hi.baidu.com/516%D0%A1%C5%DA/blog/item/30a79ede7738d51962279808.html

posted on 2011-05-20 16:53  @编程浪子@  阅读(6137)  评论(0编辑  收藏  举报