ExecuteReader(CommandBehavior.CloseConnection)会一直关闭连接吗?

时间:2012-05-09 15:30:31

标签: c# .net database-connection

这样写这个辅助方法是否安全?它会不会关闭连接?我想知道如果一切顺利,它会,但是即使它抛出,ExecuteReader也会关闭连接吗?

    public static IEnumerable<DbDataRecord> ExecuteSelect(string commandText, DbConnection conn)
    {
        using (DbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = commandText;
            conn.Open();
            using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                foreach (DbDataRecord record in reader) { yield return record; }
            }
        }
    }

5 个答案:

答案 0 :(得分:8)

是的,即使它抛出异常也会关闭连接。 如果您未指定CommandBehavior.CloseConnection并关闭连接,则您的主叫代码无法访问阅读器的内容。

同样来自MSDN:

  

执行命令时,关联的Connection对象是   关闭关联的DataReader对象时关闭。

完成后,您应该确保阅读器已关闭。 关于所有这一切的好处是你已经将它包含在一个using语句中并且你没有使用try/catch/finally在这种情况下读者将被关闭然后关闭数据库连接。

答案 1 :(得分:2)

我个人更喜欢使用using子句关闭/处理连接,仅仅是出于并行构造的原因 - 与良好的英语语法相同。使用CommandBehavior对我来说是不平衡的,因此是不可预测的。

我告诉我的开发人员要简单,一致。如果他们忘记设置命令行为,我将不会看到它。如果他们不使用使用 ......我会看到它。

答案 2 :(得分:0)

是的它(在你正在做的使用区内)。但要访问您可能想要使用的数据,而不是迭代其内容。

DbDataReader.read。

答案 3 :(得分:0)

我知道问题与关闭连接有关;但是,连接不会被处理掉。要自行处理连接,您还需要将using块括起来:

using (DBConnection conn = new ...)
{
    using (DbCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = commandText;
        conn.Open();
        using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
            foreach (DbDataRecord record in reader) { yield return record; }
        }
    }
}

更新我认为这是一个有趣的问题所以我写了以下测试:

string connString = @"Data Source=.\SQLEXPRESS;Initial Catalog=msdb;Integrated Security=True;";
SqlConnection conn = new SqlConnection(connString);

try
{
using (SqlCommand cmd = conn.CreateCommand())
    {
        cmd.CommandText = "select  from MSdbms"; 
        conn.Open();
        Console.WriteLine(conn.State);
        using (IDataReader reader = cmd.ExecuteReader())//Will throw an exception - Invalid SQL syntax -see setting CommandText above
        {
            Console.WriteLine("here");
        }
    }
}
catch(Exception ex)
{  Console.WriteLine(conn.State); } //prints Open

如果行using (IDataReader reader = cmd.ExecuteReader())更改为:using (DbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)),则会打印已关闭。要记住的事情。

答案 4 :(得分:0)

如果您关闭阅读器和/或用using(var reader ...){}阻止包裹阅读器,请确保您的连接已关闭。

没有包装,并且没有reader.Close()关闭阅读器保持我的连接打开。