使用可能有异常的多个 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 定义了 SqlDataAdapter
和 SqlCommands
。我的目标是将不同 table 的逻辑分成不同的方法
我看到了一些可能的改进:
- 不要吞下异常 (
catch (Exception){}
) - 要么处理它,要么让它冒泡。
- 您不需要关闭或处理连接 -
using
块会为您做这件事
- 您也应该将
SqlCommand
放在 using
块中。
- 您传入了一个连接,但随后覆盖了 local 变量 - 传入的连接未更改。为什么要有参数?
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);
}
}
我正在使用 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 定义了 SqlDataAdapter
和 SqlCommands
。我的目标是将不同 table 的逻辑分成不同的方法
我看到了一些可能的改进:
- 不要吞下异常 (
catch (Exception){}
) - 要么处理它,要么让它冒泡。 - 您不需要关闭或处理连接 -
using
块会为您做这件事 - 您也应该将
SqlCommand
放在using
块中。 - 您传入了一个连接,但随后覆盖了 local 变量 - 传入的连接未更改。为什么要有参数?
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);
}
}