今天我查看了一些遗留代码,我开始担心。需要明确关闭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();
}
答案 0 :(得分:2)
没有。 SqlCommand.Dispose
基本上是无操作¹,它不会关闭SqlDataReader
。
从技术上讲,关闭SqlConnection
应关闭所有资源,详情请参阅此问题:
但是,这是不好的做法 - 您依赖于SqlClient库的实现细节。 “正确”的方式是(通过Dispose
或using
)处置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
}
}
}
}
¹请注意,对于OleDbCommand
和SqlCeCommand
等其他库的命令类,情况并非如此,因此不要养成不处理命令的习惯。
答案 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.