代码之家  ›  专栏  ›  技术社区  ›  micahhoover

按顺序封装和处理SqlClient对象

  •  2
  • micahhoover  · 技术社区  · 7 年前

    我正在尝试分层我的Sql客户机对象调用,以便可靠地处理它们。像这样:

    打开数据库连接->创建命令->读取结果->关闭 命令->关闭数据库连接

    到目前为止,当我用同样的方法做所有这些事情时,这已经成功了。

    问题是这很容易出错。还有一堆乱七八糟的东西。

    当我尝试创建一个公共方法来处理这个问题时,它会清除所有内容并返回一个读卡器,在读卡器启动之前连接就会关闭。

    //closes connection before it can be read...apparently the reader doesn't actually have any data at that point ... relocating to disposable class that closes on dispose
    public SqlDataReader RunQuery(SqlCommand command)
    {
        SqlDataReader reader = null;
        using (var dbConnection = new SqlConnection(_dbConnectionString))
        {
            try
            {
                dbConnection.Open();
    
                command.Connection = dbConnection;
    
                reader = command.ExecuteReader();  // connection closed before data can be read by the calling method
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            finally
            {
                dbConnection.Close();
            }
        }
    
        return reader;
    }
    

    我可以通过创建自己的实现IDispose(etc)的类来解决这个问题,但是当我用相同的using语句包装它时,它占用的行数与数据库连接using语句占用的行数一样多。

    在一个负责所有这些工件并关闭连接的可重复类中,如何处理数据库连接?

    2 回复  |  直到 7 年前
        1
  •  1
  •   David Browne - Microsoft    7 年前

    所以没有办法创建一个可重用的方法来隐藏所有/大部分嵌套的using语句?

    从方法返回DataReader时支持一种特定的模式,如下所示:

    static IDataReader GetData(string connectionString, string query)
    {
        var con = new SqlConnection(connectionString);
        con.Open();
        var cmd = con.CreateCommand();
        cmd.CommandText = query;
        var rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
        return rdr;
    }
    

    然后可以在 using

        using (var rdr = GetData(constr, sql))
        {
            while (rdr.Read())
            {
                //process rows
            }
        } // <- the DataReader _and_ the connection will be closed here
    
        2
  •  3
  •   Kevin K.    7 年前

    您可以创建一个包含可重用的开放数据库连接的类,但我建议将数据读入列表并返回结果:

    public List<object> RunQuery(SqlCommand command)
    {
        List<object> results = new List<object>();
        using (var dbConnection = new SqlConnection(_dbConnectionString))
        {
            try
            {
                dbConnection.Open();
    
                command.Connection = dbConnection;
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        // Repeat for however many columns you have
                        results.Add(reader.GetString(0));
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
    
        return results;
    }
    

    reader.GetString here

    编辑:如前所述,我删除了你的 finally 声明。这是因为你的 using 声明本质上是在做同样的事情。你可以想出一个 使用 try - 最后 语句已退出。