我今天一直在研究如何使用“using”语句来处理我的sql对象。 但是我仍然对何时以及如何捕获不可预见的错误感到困惑。我在这里有一个简单的方法,并且会感谢任何输入正确或我做错了什么?
private BindingList<My_Object> Search(int ID)
{
string strSelectStatement =
"SELECT 'coloumns' " +
"FROM 'table' " +
"WHERE ID = @ID;";
DataTable dt = new DataTable();
try
{
using (SqlConnection sqlConn = new SqlConnection(m_SQLConnectionString))
{
using (SqlCommand cmd = new SqlCommand(strSelectStatement, sqlConn))
{
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
using (SqlDataAdapter adpt = new SqlDataAdapter(cmd))
{
adpt.Fill(dt);
}
}
}
My_Object myObject;
BindingList<My_Object> myObjectList = new BindingList<My_Object>();
foreach (DataRow row in dt.Rows)
{
myObject = new My_Object();
//Fill/set myObject properties and add to myObject list
}
return myObjectList;
}
catch (Exception)
{
//throw the the exception with its stack trace up to the main call
throw;
}
}
所以我在这里捕获的是在运行adapter.Fill时,或者在构建myObject / list时出现错误时捕获错误。
由于
答案 0 :(得分:2)
不要发现“不可预见的”错误,因为如果真的无法预料,你无能为力。
除非您当然希望以某种方式处理这些错误,比如记录消息 - 但系统会为您执行此操作 - 然后它们不再是“不可预见的”,因为您期望它们。
对于发布的代码,存在问题。首先,try / catch
可以说是尝试太多,并且鉴于你有using
s,这是没有意义的(如果不是例外的话)处理。)它也捕获了一个通用的例外,这是非常沮丧的; catch
es应该用于过滤那些你可以处理的东西,并按照适当的顺序。仅仅抓住throw
也毫无意义。
答案 1 :(得分:2)
如果您对此无能为力,请不要捕获异常。如果你抓住它们是为了清理非托管资源或用于记录目的。
您可以查看MSDN“处理例外的最佳做法”http://msdn.microsoft.com/en-us/library/seyhszts.aspx
答案 2 :(得分:2)
在C#中。 using语句定义要处置的项的范围。可以为任何实现IDisposable接口的对象调用此方法。
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
因此,如果您不必使用块,则可以在类上调用dispose方法来释放/清理对象创建的资源。
当调用实现IDisposable接口的类时,try / finally模式确保即使异常中断了您的应用程序也会处理非托管资源。
如果在using语句的情况下抛出异常,则仍会调用dispose。您也可以使用语句堆叠
using (SqlConnection sqlConn = new SqlConnection(m_SQLConnectionString))
using (SqlCommand cmd = new SqlCommand(strSelectStatement, sqlConn))
{
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = ID;
using (SqlDataAdapter adpt = new SqlDataAdapter(cmd))
{
adpt.Fill(dt);
}
}
关于异常处理。捕获所有异常尝试捕获类或方法抛出的特定异常是不明智的。您可以在msdn上查看异常详细信息,以便SQLConnection:http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.open.aspx
出现InvalidOperationException
无法在未指定数据源或服务器的情况下打开连接。
或
连接已经打开。
SQLEXCEPTION
打开连接时发生连接级别错误。如果Number属性包含值18487或18488,则表示指定的密码已过期或必须重置。有关详细信息,请参阅ChangePassword方法。
所以这些是你应该照顾的例外。希望有所帮助!
答案 3 :(得分:1)
您不需要try..catch {throw}。这与没有try..catch块一样。
如果要记录显示友好消息的错误,请将代码放入catch {}。
即使代码崩溃,仍会在SqlConnection上调用Dispose。
答案 4 :(得分:0)
您可以在try语句的末尾捕获多个异常。这意味着您可以捕获可能发生的每种不同类型的错误,即InvalidOperationException / SqlException。 MSDN在此解释:
http://msdn.microsoft.com/en-us/library/ms173162(v=vs.80).aspx
答案 5 :(得分:0)
由于您已将整个代码包含在try / Catch中,因此它将捕获try / catch代码块中引发的所有错误。 但是不要按照这个apprach只捕获你想要处理或记录的那些错误。 这是推荐的,因为捕获错误是一种开销。