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

只是想知道在使用这种形式的数据库命令/连接时是否存在任何典型问题。有什么“更好”的吗?任何可能帮助我提高TSQL/C技能的其他东西都将不胜感激!谢谢大家!

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)
更为简洁。绝对好