【问题标题】:Ado.Net: Does closing SqlCommand cause closing DataReaderAdo.Net:关闭 SqlCommand 是否会导致关闭 DataReader
【发布时间】:2015-04-29 15:56:35
【问题描述】:

今天我浏览了一些遗留代码,我开始担心。需要明确关闭DataReader

我的问题是:关闭SqlCommand 是否也会关闭关联的DataReader

这是我的代码:

    using (var conn = new SqlConnection(this.ConnectionString))
    {
        conn.Open();

        using (var cmd = conn.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "House_GetHouseById";

            SqlCommandBuilder.DeriveParameters(cmd);

            cmd.Parameters["@HouseId"].Value = houseId;

            var reader = cmd.ExecuteReader())

            while (reader.Read())
            {

            }
        }
    }

在这个来自 msdn 的 sn-p 命令没有明确关闭:

string queryString =
    "SELECT OrderID, CustomerID FROM dbo.Orders;";

using (SqlConnection connection =
           new SqlConnection(connectionString))
{
    SqlCommand command =
        new SqlCommand(queryString, connection);
    connection.Open();

    SqlDataReader reader = command.ExecuteReader();

    // Call Read before accessing data.
    while (reader.Read())
    {
        Console.WriteLine(String.Format("{0}, {1}",
            reader[0], reader[1]));
    }

    // Call Close when done reading.
    reader.Close();
}

【问题讨论】:

  • 最好也将读者包裹在 using 子句中

标签: c# ado.net


【解决方案1】:

没有。 SqlCommand.Dispose 本质上是无操作¹,它不会关闭您的 SqlDataReader

从技术上讲,关闭SqlConnection 应该会关闭所有资源,详情请参阅此问题:

但是,这是一种不好的做法——您依赖于 SqlClient 库的实现细节。 “正确”的方式是处理(通过Disposeusing)所有IDisposable。因此,您的代码应编写如下:

using (var conn = new SqlConnection(this.ConnectionString))
{
    conn.Open();

    using (var cmd = conn.CreateCommand())
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "House_GetHouseById";

        SqlCommandBuilder.DeriveParameters(cmd);

        cmd.Parameters["@HouseId"].Value = houseId;

        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // do something
            }
        }
    }
}

¹ 请注意,对于 OleDbCommandSqlCeCommand 等其他库的命令类,情况并非如此,因此请不要养成不释放命令的习惯。

【讨论】:

    【解决方案2】:

    您总是可以将 datareader 包装在 using 指令中,以便在执行超出范围时立即关闭命令,就像 sqlcommand 一样

        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            if (reader != null)
            {
                while (reader.Read())
                {
                    //do something
                }
            }
        } // reader is closed here
    
    reader.Close(); //is another way but its too easy to be forgotten.
    

    【讨论】:

    • 不知道谁赞成这个,但问题是 “关闭 SqlCommand 会导致关闭 DataReader”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 2015-08-31
    • 2011-07-31
    • 1970-01-01
    • 2011-03-23
    • 2013-11-10
    • 1970-01-01
    相关资源
    最近更新 更多