C#数据库的连接和非查询执行
只是想知道在使用这种形式的数据库命令/连接时是否存在任何典型问题。有什么“更好”的吗?任何可能帮助我提高TSQL/C技能的其他东西都将不胜感激!谢谢大家!C#数据库的连接和非查询执行,c#,sql-server,tsql,sqlconnection,sqlcommand,C#,Sql Server,Tsql,Sqlconnection,Sqlcommand,只是想知道在使用这种形式的数据库命令/连接时是否存在任何典型问题。有什么“更好”的吗?任何可能帮助我提高TSQL/C技能的其他东西都将不胜感激!谢谢大家! private void Approval_Status(object sender, EventArgs e) { Button Approval = (Button)sender; /* * Boolean determining if the request was approv
private void Approval_Status(object sender, EventArgs e)
{
Button Approval = (Button)sender;
/*
* Boolean determining if the request was approved or denied
*/
Boolean Status = false;
if (ValidateApproval(Approval.Text.Trim().ToUpper()) == true)
{
SqlCommand cmd0 = new SqlCommand();
cmd0.Connection = db.con(user.Authority);
cmd0.CommandType = CommandType.Text;
cmd0.CommandText = "UPDATE [TBL_REQUEST] " +
"SET [TBL_REQUEST].[REQUEST_STATUS]=@Status, [TBL_REQUEST].[APPROVED_BY]=@Approver, " +
"[TBL_REQUEST].[DATE_APPROVED]=@Date, [TBL_REQUEST].[PRINTED_NAME]=@Name, " +
"[TBL_REQUEST].[TITLE]=@Title, [TBL_REQUEST].[PTO_USED]=@Used " +
"WHERE [TBL_REQUEST].[ID]=@ID; ";
if (Approval.Text.ToUpper() == codes.RequestApproved)
{
cmd0.Parameters.AddWithValue("@Status", SqlDbType.VarChar).Value = codes.RequestApproved;
Status = true ;
}
else
{
cmd0.Parameters.AddWithValue("@Status", SqlDbType.VarChar).Value = codes.RequestDenied;
Status = false;
}
cmd0.Parameters.AddWithValue("@Approver", SqlDbType.VarChar).Value = user.User;
cmd0.Parameters.AddWithValue("@Date", SqlDbType.Date).Value = DateTime.Today.ToShortDateString();
cmd0.Parameters.AddWithValue("@Name", SqlDbType.VarChar).Value = txtApproval.Text.Trim();
cmd0.Parameters.AddWithValue("@Title", SqlDbType.VarChar).Value = user.Title;
cmd0.Parameters.AddWithValue("@Used", SqlDbType.Float).Value = (float)nudUsed.Value;
cmd0.Parameters.AddWithValue("@ID", SqlDbType.VarChar).Value = txtID.Text.Trim();
/*
* Execute our non-query
*/
db.conEstablished.Open();
cmd0.ExecuteNonQuery();
db.conEstablished.Close();
/*
* Dispose our resources
*/
cmd0.Dispose();
ClearRequestsPanel();
/*
* Inform our user of a successful update
*/
if (Status == true)
{
MessageBox.Show(msg.RequestApproved);
}
else if (Status == false)
{
MessageBox.Show(msg.RequestDenied);
}
}
看起来您可能正在尝试创建自己的连接池。不要这样做:
- 对所有可使用资源使用
语句。这包括
和SqlConnection
。这样,即使抛出异常,也会释放资源SqlCommand
- 为每个数据库操作创建一个新的
,并让系统管理真正的网络连接池SqlConnection
db.con(…)
和db.conbuilded
,但听起来很可能只有一个连接,这意味着在多线程环境中无法安全使用此代码。有一个helper方法来创建SqlConnection
,这很好,但是每次都应该创建一个新的连接,然后在操作完成后处理它
此外,您应该开始遵循.NET命名约定,并执行以下代码:
if (Status == true)
{
MessageBox.Show(msg.RequestApproved);
}
else if (Status == false)
{
MessageBox.Show(msg.RequestDenied);
}
。。。最好写为:
MessageBox.Show(Status ? msg.RequestApproved : msg.RequestDenied);
看起来您可能正在尝试创建自己的连接池。不要这样做:
- 对所有可使用资源使用
语句。这包括
和SqlConnection
。这样,即使抛出异常,也会释放资源SqlCommand
- 为每个数据库操作创建一个新的
,并让系统管理真正的网络连接池SqlConnection
db.con(…)
和db.conbuilded
,但听起来很可能只有一个连接,这意味着在多线程环境中无法安全使用此代码。有一个helper方法来创建SqlConnection
,这很好,但是每次都应该创建一个新的连接,然后在操作完成后处理它
此外,您应该开始遵循.NET命名约定,并执行以下代码:
if (Status == true)
{
MessageBox.Show(msg.RequestApproved);
}
else if (Status == false)
{
MessageBox.Show(msg.RequestDenied);
}
。。。最好写为:
MessageBox.Show(Status ? msg.RequestApproved : msg.RequestDenied);
使用
是处理SqlConnection等一次性对象的“正确”方法
代码的部分问题在于,如果查询导致异常,则将跳过此行,因为异常将从方法中中断:
cmd0.Dispose();
使用using
时,始终会调用dispose,即使异常退出块(在内部,它只是将代码包装在try/catch
中,并将调用放到catch块中的.dispose()
)
您还应该注意,SqlConnection
类在内部处理池。实际上,它不是与数据库的单一开放网络连接。使用
是处理诸如SqlConnection之类的一次性对象的“正确”方法
代码的部分问题在于,如果查询导致异常,则将跳过此行,因为异常将从方法中中断:
cmd0.Dispose();
使用using
时,始终会调用dispose,即使异常退出块(在内部,它只是将代码包装在try/catch
中,并将调用放到catch块中的.dispose()
)
您还应该注意,
SqlConnection
类在内部处理池。它实际上不是一个到DB的单一开放网络连接。您的代码应该是这样的。显然,我这里有其他地方定义的变量,但希望这能让您更好地了解如何使用using
using(var dbconn = new SqlConnection(connectionString))
{
using (var dbcmd = new SqlCommand(storedProcedure, dbconn))
{
dbcmd.CommandType = CommandType.StoredProcedure;
dbcmd.Parameters.AddRange(sqlParameters.ToArray());
dbconn.Open();
return dbcmd.ExecuteNonQuery();
}
}
您的代码应该是这样的。显然,我这里有其他地方定义的变量,但希望这能让您更好地了解如何使用
using
using(var dbconn = new SqlConnection(connectionString))
{
using (var dbcmd = new SqlCommand(storedProcedure, dbconn))
{
dbcmd.CommandType = CommandType.StoredProcedure;
dbcmd.Parameters.AddRange(sqlParameters.ToArray());
dbconn.Open();
return dbcmd.ExecuteNonQuery();
}
}
什么是
db.con
?而且using
语句是语言的一部分-它不是函数。使用此表单时的典型问题是忘记cmd0.Dispose()
调用,而using
会处理该调用。:)@大卫:不仅仅是忘记了,而且没有把它放到最后
块中……请记住x==true=>x
。你不需要将布尔表达式与true
@IliaG进行比较,我个人认为使用这种形式的布尔表达式的名字不好,因为if(Status)
读起来比if(Status==true)
读起来稍微差一点。我个人更愿意看到名字很好的布尔表达式,这样它读起来就很好if(IsApproved)
或if(Approved)
什么是db.con
?而且using
语句是语言的一部分-它不是函数。使用此表单时的典型问题是忘记cmd0.Dispose()
调用,而using
会处理该调用。:)@大卫:不仅仅是忘记了,而且没有把它放到最后
块中……请记住x==true=>x
。你不需要将布尔表达式与true
@IliaG进行比较,我个人认为使用这种形式的布尔表达式的名字不好,因为if(Status)
读起来比if(Status==true)
读起来稍微差一点。我个人更愿意看到名字很好的布尔表达式,这样它读起来就很好if(IsApproved)
或if(Approved)
MessageBox.Show(状态?msg.RequestApproved:msg.RequestDenied)。。。这很有帮助!学到了一些新东西,谢谢@JoshuaVolearix:即使您想使用if
版本,最好使用if(Status){…}else{…}
。首先,如果它不是真的,那么它肯定是假的——在我看来,使用if(foo)
或if(!foo)
比使用if(foo==true)
或if(foo==false)
更为简洁。绝对好