【问题标题】:SQLConnection with the Using statement, calling SQLDataReader from inside it?SQLConnection 与 Using 语句,从里面调用 SQLDataReader 吗?
【发布时间】:2010-12-17 16:03:09
【问题描述】:

只是想确保这是调用连接并从数据库中获取数据的最佳方式,或者我应该如何在 using 语句之外调用数据读取器? (为了更快地关闭连接?)或者您有什么个人需要改变的吗?

using (SqlConnection cn = new SqlConnection(connStr))
        {
            using (SqlCommand cm = new SqlCommand(connStr, cn))
            {  
                cm.CommandType = CommandType.StoredProcedure;
                cm.CommandText = "GetExchRatesByDate";
                cm.Parameters.Add("@Date", SqlDbType.VarChar).Value = txtStartDate.Text;
                cn.Open();
                SqlDataReader dr = cm.ExecuteReader();

                while (dr.Read())
                {
                    firstName = (string)dr["GivenName"];
                    lastName = (string)dr["sn"];;
                }
                dr.Close();
            }
        }

【问题讨论】:

    标签: asp.net sql using


    【解决方案1】:

    您无法在 using 语句之外成功调用 datareader,因为它需要打开的连接才能读取数据。

    连接将按照您的方式快速关闭,甚至不会真正“关闭”。它将返回到连接池(假设您正在使用一个)。既然您可能是,您无需担心在此上下文中连接关闭的速度有多快,因为需要连接的应用程序的其他部分将从池中获取可用的连接。这是假设您没有真正高流量的应用程序,它在这种情况下可能变得很重要,但是有很多很多并发用户,您可以通过增加池中的连接数来缓解这个问题.

    Chris 也提出了一个很好的观点:它应该在 using 语句中:

      SqlDataReader dr = cm.ExecuteReader();
    
                    while (dr.Read())
                    {
                        firstName = (string)dr["GivenName"];
                        lastName = (string)dr["sn"];;
                    }
                    dr.Close();
    

    在这种情况下,如果您的阅读器抛出异常,它将永远无法到达dr.Close();,因此它将保持打开的时间比它需要的时间长很多(甚至可能在应用程序的生命周期内)。

    Data Reader

    【讨论】:

    • 谢谢,只是想确定这是一种可接受的数据获取方式。我将继续使用此代码
    【解决方案2】:

    不仅不能在using 语句之外调用SqlDataReader,因为所有在变量中声明的变量都将被释放,而且你需要一个打开的连接来读取数据,你最好编写一个对象,它将被返回,甚至是你的对象列表。

    public class MyObject {
        public string FirstName { get; set; }
        public string Surname { get; set; }
    }
    
    public IEnumerable<MyObject> GetObjects() {
        ICollection<MyObject> myObjects = new List<MyObject>();
    
        using (SqlConnection cn = new SqlConnection(connStr))
        {
            using (SqlCommand cm = new SqlCommand(connStr, cn))
            {  
                cm.CommandType = CommandType.StoredProcedure;
                cm.CommandText = "GetExchRatesByDate";
                cm.Parameters.Add("@Date", SqlDbType.VarChar).Value = txtStartDate.Text;
                cn.Open();
    
                using(SqlDataReader dr = cm.ExecuteReader()) 
                    while (dr.Read()) {
                        MyObject myObject = new MyObject();
                        myObject.FirstName = (string)dr["GivenName"];
                        myObject.Surname = (string)dr["sn"];
                        myObjects.Add(myObject);
                    }
            }
        }
        return myObjects;
    }
    

    【讨论】:

      【解决方案3】:

      datareader 实现了 IDisposable,因此它也应该包含在 using 子句中。其他一切看起来都不错。

      【讨论】:

        【解决方案4】:

        其他人已经介绍过了,但我喜欢使用的另一件事是 AddWithValue:

        cm.Parameters.Add("@Date", SqlDbType.VarChar).Value = txtStartDate.Text;
        

        可以写成:

        cm.Parameters.AddWithValue("@Date", txtStartDate.Text);
        

        【讨论】:

          【解决方案5】:

          我会考虑将 SQLConnection 放入工厂方法中。 (如果它被称为负载)

          我也不会在 dr.Read 周围有一个 while 循环 你只期待一个答案,那么当没有结果或有很多结果时会发生什么???? 不太确定我是否喜欢演员阵容,但可能还可以。

          我认为您对该代码进行了单元测试,并传入了连接字符串等...(显然,工厂的想法会使单元测试变得更加困难,因此可能不值得这样做...)

          您的 using 语句对我来说看起来不错。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-05
            • 1970-01-01
            • 1970-01-01
            • 2019-02-05
            • 2013-06-03
            • 2011-02-25
            • 2012-04-26
            相关资源
            最近更新 更多