Ado.Net:关闭SqlCommand会导致关闭DataReader

时间:2015-04-29 07:14:11

标签: c# ado.net

今天我查看了一些遗留代码,我开始担心。需要明确关闭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命令的这个片段中没有明确关闭:

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();
}

2 个答案:

答案 0 :(得分:2)

没有。 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等其他库的命令类,情况并非如此,因此不要养成不处理命令的习惯。

答案 1 :(得分:1)

您总是可以将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.