【问题标题】:C# Connection And NonQuery Execution To Database [closed]到数据库的 C# 连接和非查询执行 [关闭]
【发布时间】:2012-12-17 04:50:29
【问题描述】:

只是想知道在使用这种形式的数据库命令/连接时是否存在任何典型问题。有什么“更好”的吗?任何其他可能帮助我提高我的 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);
            }
        }

【问题讨论】:

  • 什么是db.conusing 语句是语言的一部分——它不是函数。
  • 使用此表单时的典型问题是忘记了cmd0.Dispose() 调用,using 负责处理该调用。 :)
  • @David:不仅忘记了,还没有把它放在finally 块中......
  • 请记住x == true => x。您无需将布尔表达式与true 进行比较。
  • @IliaG 就我个人而言,我可以接受带有错误名称的布尔值,因为if(Status) 的读数比if (Status==true) 略差一点,就我个人而言,我宁愿看到名称良好的布尔值,所以它读起来很好if(IsApproved)if(Approved)

标签: c# sql-server tsql sqlconnection sqlcommand


【解决方案1】:

看起来您可能正在尝试创建自己的连接池。不要那样做:

  • 对所有一次性资源使用using 语句。这包括SqlConnectionSqlCommand。这样,即使抛出异常,资源也会被释放
  • 为每个数据库操作创建一个新的SqlConnection,并让系统管理池化真实网络连接。

不清楚db.con(...)db.conEstablished 是什么,但听起来你很可能只有一个连接 - 这意味着你不能在一个多线程环境。有一个帮助方法来创建SqlConnection 很好,但它应该每次都创建一个新的,然后在操作完成时将其释放。

此外,您应该开始遵循 .NET 命名约定和以下代码:

if (Status == true)
{
    MessageBox.Show(msg.RequestApproved);
}
else if (Status == false)
{
    MessageBox.Show(msg.RequestDenied);
}

... 最好写成:

MessageBox.Show(Status ? msg.RequestApproved : msg.RequestDenied);

【讨论】:

  • MessageBox.Show(状态 ? msg.RequestApproved : msg.RequestDenied); ...很有帮助!学到了新东西,谢谢!
  • @JoshuaVolearix:即使你想使用if 版本,使用if (Status) { ... } else { ... } 会更好。一方面,如果它不是真的,那肯定是假的——而且通常使用if (foo)if (!foo) 而不是if (foo == true)if (foo == false) 是更简洁的IMO 风格。
  • 很高兴知道,我现在只用了两个星期的 C# 编程,除了 ABSOLUTE 基础知识之外的所有其他内容通常都是自学的。初学者书籍中并没有真正涵盖此类内容!
【解决方案2】:

using 是处理 SqlConnection 等一次性对象的“正确”方式。

您的代码的部分问题是,如果查询导致异常,则将跳过此行,因为异常会中断方法:

cmd0.Dispose();

使用using 时,将始终调用 dispose,即使异常退出块(在内部它只是将代码包装在 try/catch 中并将对 .Dispose() 的调用放入 catch 块中。)

您还应该注意SqlConnection 类在内部处理池。它实际上不是一个到 DB 的开放网络连接。

【讨论】:

    【解决方案3】:

    您的代码应如下所示。显然我在这里有在别处定义的变量,但希望这能让您更好地了解如何使用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();
        }
    }
    

    【讨论】:

    • 感谢您实际回答问题。我正在寻找“使用”的正确语法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 2016-04-11
    相关资源
    最近更新 更多