11

像这样编写这个辅助方法是否安全?它会一直关闭连接吗?我知道如果一切顺利,它会的,但是 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; }
            }
        }
    }
4

5 回答 5

9

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

同样来自 MSDN:

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

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

于 2012-05-09T15:35:09.047 回答
2

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

我经常告诉我的开发人员要简单而一致。
好像他们忘记设置CommandBehavior...

我不会看到它......
但如果他们不使用using声明......
看到它,因为它非常重要。

于 2013-06-04T19:47:38.287 回答
0

是的,它会(在你正在做的 using 块内)。但是要访问您可能想要使用的数据 While DbDataReader.read 而不是迭代其内容。

于 2012-05-09T15:35:02.987 回答
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))则打印Closed。要记住的事情。

于 2012-05-09T15:44:05.583 回答
0

如果您关闭阅读器和/或使用using(var reader ...){}YES包装阅读器,则确保您的连接已关闭。

不包装也不关闭阅读器并reader.Close()保持我的连接打开。

于 2015-05-20T20:49:56.533 回答