C# SqlCommand正确关闭连接

C# SqlCommand正确关闭连接,c#,sql-server,sqlconnection,C#,Sql Server,Sqlconnection,我最近一直在做一个老项目。在这个项目中,我发现以前的同事已经创建了一些常用的方法来打开到数据库的连接。但我怀疑这个过程是否真的在查询完成后处理IDispose的连接 方法如下: 连接数据库 /// <summary> /// This method creates a connection object to the database. /// </summary> /// <returns>a new SQL Connection</retur

我最近一直在做一个老项目。在这个项目中,我发现以前的同事已经创建了一些常用的方法来打开到数据库的连接。但我怀疑这个过程是否真的在查询完成后处理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;
}

您认为这个过程会正确释放所有连接吗?

SqlConnection
还实现了
IDisposable
接口,因此您也必须关闭连接。因此,您还应该使用块将连接包装在
中。

代码不安全。处理/关闭读卡器不会自动关闭连接,因为您可能希望在同一连接上执行多个命令。即使使用该选项确实关闭了连接,在使用
块输入
之前可能出现的异常也会使连接保持打开状态

典型的方法是使用
语句将连接、命令和读取器包装在
中:

using(var con=new SqlConnection(connectionString))
using(var command=new SqlCommand(sql,con))
{
    con.Open();
    using(var reader=command.ExecuteReader())
    {
    ....
    }
}

不,您的代码没有正确释放所有连接,因为它们已在其他答案中确认。 然而,修改一个旧程序可能是一场噩梦,我建议这样的方法

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")));
        }
    }
}
类程序
{
静态IEnumerable InteractionGetData(字符串查询)
{
使用(var-connection=new-SqlConnection(@“数据源=localhost;集成安全性=SSPI;”))
{
connection.Open();
使用(var命令=新的SqlCommand(查询、连接))
{
使用(var reader=command.ExecuteReader())
{
while(reader.Read())
{
回传阅读器;
}
}
}
}
}
静态void Main(字符串[]参数)
{
foreach(InteractionGetData中的变量读取器(“从产品中选择不同的产品名称”))
{
Console.WriteLine(reader.GetString(reader.GetOrdinal(“ProductName”));
}
}
}

否。关闭读卡器并不意味着命令或连接已关闭。即使是这样,在打开读卡器之前的任何异常都会使连接保持打开状态。为什么不使用典型的方法—在using语句中包装连接、命令和读取器?如果使用
query.ExecuteReader(commandbehavior.CloseConnection)
执行读取器,则当读取器关闭时,连接将关闭(释放时会发生这种情况)。但是,最好使用using语句。更清楚的是代码在做什么,并确保事情得到正确处理,而不仅仅是关闭。查看文档的示例,了解如何安全地调用
ExecuteReader
,并确保即使发生异常也关闭连接。你会注意到这个例子比你的代码要简单得多,谢谢。我还应该使用passCommandBehavior.CloseConnection to ExecuteReader()方法吗?不必这样做,因为外部
使用
显式关闭连接。
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")));
        }
    }
}