【问题标题】:Does my code close connection to SQL Server我的代码是否关闭与 SQL Server 的连接
【发布时间】:2018-04-24 14:34:07
【问题描述】:

所以方法 GetAllData 是我连接到数据库的通用方法之一,在这里,因为我必须一次向数据库中添加多个记录,所以我需要一个连接多个命令才能运行。所以我的问题是这种连接方式是否正确关闭了数据库,或者如果您对我的代码有任何改进,请与我分享。

       var conn = new SqlConnection(ConnString);
        conn.Open();
        var data = new Dictionary<string, List<object>>();
        foreach (var h in hours)
        {
            data += SqlUniversal.GetAllData(query,//idk how I will collect the data yet... i know += wouldnt work for dictionary
                new[] {
                    //some parameters
                },
                conn);
        }
//Here is the method, above is how I call it.
        public static Dictionary<string, List<object>> GetAllData(string command, SqlParameter[] pars, SqlConnection conn)
        {
        if (conn == null)
        {
            conn = new SqlConnection(ConnString);
            conn.Open();
        }
        var res = new Dictionary<string, List<object>>();
        using (conn)
        {
            using (var cmd = new SqlCommand(command, conn))
            {
                cmd.Parameters.AddRange(pars);
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                        for (var i = 0; i < reader.VisibleFieldCount; i++)
                        {
                            if (reader.GetValue(i) == DBNull.Value)
                                continue;

                            var name = reader.GetName(i);

                            if (res.ContainsKey(name))
                                res[name].Add(reader.GetValue(i));

                            else
                                res.Add(name, new List<object> {reader.GetValue(i)});
                        }

                    return res;
                }
            }
        }
    }

【问题讨论】:

  • 简而言之,它可以保持打开一段时间,直到垃圾收集器完成它
  • 是的,它确实会关闭它(最终),但是你应该考虑让方法拥有连接,如果它是null一开始就创建它,那么为什么要在调用方法中打开它?调用此方法后,无论如何它都会第一次关闭。由于您没有重新打开连接,我可以看到这是一个问题。让方法拥有它并创建它。
  • using 语句 确保即使在调用对象上的方法时发生异常也会调用 Dispose:docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
  • 答案是每个人都对代码的某些部分是正确的,第一个代码没有使用,有一个打开和没有关闭,这会像难闻的气味一样留下来。但是,您的方法确实有使用,因此应该关闭它。因此,如果您快速连续调用这对,您会看到开放连接的增加
  • 为什么要在代码中创建一个连接,然后将该连接传递给一个方法,然后再创建一个新连接?为什么不停止传递连接并在您的方法中创建它?你处理连接的方式真的很脆弱。

标签: c# sql-server


【解决方案1】:

可能更好的方法是让监督方法管理连接:

public void SomeDataMethod()
{
    using (var conn = new SqlConnection(ConnString))
    {
        conn.Open();
        var data = new Dictionary<string, List<object>>();
        foreach (var h in hours)
        {
            data += SqlUniversal.GetAllData(query,
                new[] {
                    //some parameters
                },
                conn);
        }
    }
}

并从GetData 方法中删除using (conn)

public static Dictionary<string, List<object>> GetAllData(string command, SqlParameter[] pars, SqlConnection conn)
{
    var res = new Dictionary<string, List<object>>();
    using (var cmd = new SqlCommand(command, conn))
    {
        cmd.Parameters.AddRange(pars);
        using (var reader = cmd.ExecuteReader())
        {
          //...
          return res;
        }
    }
}

现在SomeDataMethod 控制连接生命周期,GetData 不用担心连接管理。

【讨论】:

  • 这很好,但在某些情况下,在我的代码中我只执行一个查询,所以在 main 方法中我不想控制连接,但我会考虑这个
  • @DanielSuchan 确实是“经销商选择”,但只有一种方法应该控制/创建连接,而不是两者。如果您想将连接处理移至GetData 方法中,请务必这样做,但不要将连接作为参数传递。
  • 但既然我现在知道 conn 池的工作原理,我可能会使用您的解决方案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
  • 2018-11-27
  • 1970-01-01
  • 2016-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多