使用可能有异常的多个 using 语句的正确方法是什么?

What is the right way to use multiple using statements with possible exception?

我正在使用 SqlConnection、SqlDataAdapter 和 SqlCommand。

我只是想知道下面的代码是否正确,如果可能的话,更好的方法是什么。

private void FillWithData(int id)
{
    try
    { 
       LoadTable1(id);
    }
    catch(Exception ex){throw ex}
}

private void LoadTable1(SqlConnection conn, int id)
{
   try
   {
       using (conn = new SqlConnection(sConnectionString)) 
       using (SqlDataAdapter table1DA = new SqlDataAdapter ())
       {
          DataTable tblTable1 = Table1;
          SqlCommand table1CMD = getSelectTable1(conn, id);
          table1DA.SelectCommand = table1CMD;
          table1DA.Fill(tblTable1);
          table1CMD.Dispose();
       }
   }
   catch(SqlException ex)
   {
       if (conn.State == ConnectionState.Open) conn.Close();
       conn.Dispose();
       throw ex;   
   }
   finally
   {
       try
       {
          if (conn.State == ConnectionState.Open) conn.Close();
       }
       catch (Exception){}
       conn.Dispose();
   }         
}

我将使用更多方法对其他 table 执行相同的操作。目前一切都在一个方法下执行,该方法具有 try/catch 块,其中每个 table 定义了 SqlDataAdapterSqlCommands。我的目标是将不同 table 的逻辑分成不同的方法

我看到了一些可能的改进:

  1. 不要吞下异常 (catch (Exception){}) - 要么处理它,要么让它冒泡。
  2. 您不需要关闭或处理连接 - using 块会为您做这件事
  3. 您也应该将 SqlCommand 放在 using 块中。
  4. 您传入了一个连接,但随后覆盖了 local 变量 - 传入的连接未更改。为什么要有参数?
  5. throw ex; 不是最佳实践,因为您丢失了原始堆栈跟踪 - 最好只使用 throw;。由于除了关闭连接(这是不必要的)之外,您没有在 catch 块中任何事情,因此可以完全删除 catch 块。

进行这些更改只会让您:

private void FillWithData(int id)
{
    LoadTable1(id);
}
private void LoadTable1(int id)
{
   using (SqlConnection conn = new SqlConnection(sConnectionString)) 
   using (SqlDataAdapter table1DA = new SqlDataAdapter ())
   using (SqlCommand table1CMD = getSelectTable1(conn, id))
   {
      DataTable tblTable1 = Table1;
      table1DA.SelectCommand = table1CMD;
      table1DA.Fill(tblTable1);
   }
}

并且因为 SqlDataAdapter 有一个构造函数接受 SQlCommand 你可以这样做:

private void LoadTable1(int id)
{
   using (SqlConnection conn = new SqlConnection(sConnectionString)) 
   using (SqlCommand table1CMD = getSelectTable1(conn, id))
   using (SqlDataAdapter table1DA = new SqlDataAdapter (table1CMD))
   {
      table1DA.Fill(Table1);
   }
}