我发现我的代码库包含各种数据访问代码,我以两种不同的方式使用了语句。哪个是更好的方式,这两种方法有什么不同?在using语句中不实例化SqlConnection和SqlCommand可能引起的任何问题?忽略明显的不一致问题。
方法1:
public int SampleScalar(string query, CommandType queryType, SqlParameter[] parameters)
{
int returnValue = 0;
SqlConnection objConn = new SqlConnection(ConnString);
SqlCommand objCmd = new SqlCommand(query, objConn);
objCmd.CommandType = queryType;
if (parameters.Length > 0)
objCmd.Parameters.AddRange(parameters);
using (objConn)
{
using (objCmd)
{
objConn.Open();
try
{
returnValue = (int)objCmd.ExecuteScalar();
}
catch (SqlException e)
{
Errors.handleSqlException(e, objCmd);
throw;
}
}
}
return returnValue;
}
方法2:
public int SampleScalar2(string query, CommandType queryType, SqlParameter[] parameters)
{
int returnValue = 0;
using (SqlConnection objConn = new SqlConnection(ConnString))
{
using (SqlCommand objCmd = new SqlCommand(query, objConn))
{
objConn.Open();
objCmd.CommandType = queryType;
if (parameters.Length > 0)
objCmd.Parameters.AddRange(parameters);
try
{
returnValue = (int)objCmd.ExecuteScalar();
}
catch (SqlException e)
{
Errors.handleSqlException(e, objCmd);
throw;
}
}
}
return returnValue;
}
答案 0 :(得分:5)
在第一个片段中,如果在创建IDisposable
对象之后和开始使用之前发生任何异常,则将无法正确处理。在第二个实施中,没有这样的差距可能导致未发布的资源。
第一种方法可能出现的另一个问题是,您可以在处置后使用对象,这可能不会很好地结束。
您可能确保不会发生任何异常,也许您不是。一般来说,我永远不会使用第一种方法,因为我不相信自己(或任何其他人)永远不会在那个没有保护的空间中犯错误。如果不出意外的话,我需要花费时间和精力仔细查看非常以确保确定没有任何错误。你也没有从使用这种安全性较低的方法中获得任何好处。
答案 1 :(得分:1)
我总是选择第二种方法。它更容易阅读和理解在给定块的末尾处理哪些对象。它还会阻止您使用已被处置的对象。
答案 2 :(得分:1)
如果您不使用,请不要处置您的objets没有托管,并且GC没有处置
GC只处理托管的对象,并且不管理sql连接所以你必须使用use dispose进行处理
答案 3 :(得分:1)
每MSDN
您可以实例化资源对象,然后将变量传递给using语句,但这不是最佳做法。在这种情况下,在控制离开使用块之后,对象仍然在范围内,即使它可能不再能够访问其非托管资源。换句话说,它将不再完全初始化。如果您尝试使用using块之外的对象,则可能会导致抛出异常。因此,通常最好在using语句中实例化对象,并将其范围限制为使用块。
答案 4 :(得分:1)
第二个更好。请阅读http://msdn.microsoft.com/en-us/library/yh598w02.aspx上次评论。
第一个物体在处置后仍留在范围内。使用它然后不是好习惯。