SqlCommand正确关闭连接
本文关键字:连接 SqlCommand | 更新日期: 2023-09-27 17:55:06
我最近一直在做一个老项目。我在项目中发现,以前的同事已经创建了一些常用的方法来打开数据库连接。但是我对这个进程有疑问,一旦查询完成,它是否真的通过IDispose处理连接。
方法如下:
连接数据库。
/// <summary>
/// This method creates a connection object to the database.
/// </summary>
/// <returns>a new SQL Connection</returns>
public SqlConnection ConnectDB()
{
var db = new SqlConnection(ConnectionString);
db.Open();
return db;
}
public SqlDataReader GetDataReader(SqlCommand query)
{
var db = ConnectDB();
query.Connection = db;
var reader = query.ExecuteReader();
return reader;
}
然后使用GetDataReader,如下所示
var queryProduct= new SqlCommand
{
CommandText = "SELECT DISTINCT ProductName FROM Products"
};
using (var reader = Interaction.GetDataReader(queryProduct))
{
while (reader.Read())
{
var b = new Product
{
ProductName = reader.GetString(reader.GetOrdinal("ProductName"))
};
products.Add(b);
}
}
你认为这个进程会正确释放所有的连接吗?
代码不安全。处理/关闭读取器不会自动关闭连接,因为您可能希望在同一连接上执行多个命令。即使您使用的覆盖关闭连接,在您进入using
块之前可能发生的异常也会使连接保持打开状态。
典型的方法是将连接、命令和读取器封装在using
语句中:
using(var con=new SqlConnection(connectionString))
using(var command=new SqlCommand(sql,con))
{
con.Open();
using(var reader=command.ExecuteReader())
{
....
}
}
SqlConnection
也实现了IDisposable
接口,所以你也必须关闭连接。因此,您还应该在using
块中包装连接。
不,你的代码没有正确释放所有的连接,因为他们已经在其他答案中确认。鉴于修改旧程序可能是一场噩梦,我建议采用如下方法
class Program
{
static IEnumerable<SqlDataReader> InteractionGetData(string query)
{
using (var connection = new SqlConnection(@"Data Source=localhost;Integrated Security=SSPI;"))
{
connection.Open();
using (var command = new SqlCommand(query, connection))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
yield return reader;
}
}
}
}
}
static void Main(string[] args)
{
foreach (var reader in InteractionGetData("SELECT DISTINCT ProductName FROM Products"))
{
Console.WriteLine(reader.GetString(reader.GetOrdinal("ProductName")));
}
}
}