【问题标题】:c# delete multiple data from database at oncec#一次从数据库中删除多个数据
【发布时间】:2019-12-13 21:59:17
【问题描述】:

我正在尝试创建将同时从我的数据库中删除数据的循环。

这是我的代码。

using (MySqlConnection mysqlCon = new MySqlConnection(connectionString))
{
    foreach (DataGridViewRow dr in bunifuCustomDataGrid1.Rows)
    {
        int inventid = Convert.ToInt32(bunifuCustomDataGrid1.Rows[bunifuCustomDataGrid1.CurrentRow.Index].Cells[0].Value);

        mysqlCon.Open();
        MySqlCommand cmd = new MySqlCommand("DELETE FROM bookdb.book WHERE (BookID = @uid)", mysqlCon);
        cmd.Parameters.AddWithValue("uid", inventid);

        cmd.ExecuteNonQuery();

        mysqlCon.Close();
        GridFill();
    }
}

MessageBox.Show("DOne");

我可以删除多条记录,但如果秩序混乱,它就会消失。 我希望有人可以帮助我。

/////////////////////////////////////// /////////

我在下面尝试了一些答案。这是几乎对我有用的代码。

        using (MySqlConnection mysqlCon = new MySqlConnection(connectionString))
        {
            mysqlCon.Open();
            var tr = mysqlCon.BeginTransaction();

            foreach (DataGridViewRow dr in bunifuCustomDataGrid1.Rows)
            {

                var cmd = new MySqlCommand("DELETE FROM bookdb.book WHERE (BookID = @uid)");
                cmd.Connection = mysqlCon;
                cmd.Transaction = tr;
                cmd.Parameters.AddWithValue("@uid", dr.Cells["BookID"].Value ?? DBNull.Value);
                cmd.ExecuteNonQuery();
            }

            tr.Commit();
            mysqlCon.Close();

            //////////////////////////
        }

        MessageBox.Show("DOne");
        GridFill();

        ////
        ///

问题是它删除了所有行。

【问题讨论】:

  • 更典型的方法是使用数据绑定。如果您的数据受MySqlDataAdapter 的控制,您只需将其称为Update() 方法。如果您正在操作 UI 元素,则它是一个危险信号。
  • 为什么每次迭代bunifuCustomDataGrid1.Rows时都要打开和关闭连接?
  • 为什么忽略循环中的“dr”变量?如果你的 GridFill(); 做了我认为的那样,它可能不应该在那个循环中。

标签: c# .net winforms


【解决方案1】:

使用一个事务批量发送多个ExecuteNonQuery

mysqlCon.Open();
var tr = mysqlCon.BeginTransaction();

foreach (...)
{
    var cmd = new MySqlCommand();
    cmd.Connection = mysqlCon ;
    cmd.Transaction = tr;

     ...
    cmd.ExecuteNonQuery();
}

tr.Commit();
mysqlCon.Close();

【讨论】:

  • 我认为我以错误的方式使用您的代码..它一次删除了所有行..
  • 在你的 foreach 循环中放入 Debug.WriteLine($"deleting bookId {dr.Cells["BookID"].Value}") 并评论 //cmd.ExecuteNonQuery() 以首先检查它是否会删除所有正确的 bookID
【解决方案2】:

您可以以不同的方式构建查询以一次性删除所有内容:

DELETE FROM bookdb.book WHERE BookID IN (bookid1, bookid2, bookid3, ...)

虽然这有时会导致大量 SQL 查询被传递。

根据之前的答案,最好的解决方案是使用数据绑定并在所有项目都标记为删除后调用更新方法;这相当于删除事务中的所有内容。

【讨论】:

    【解决方案3】:

    根据您当前的代码,似乎一种简单的方法是迭代单元格并立即从 gridview 中获取所有 id,然后将它们发送到数据库以进行删除。

            using (MySqlConnection mysqlCon = new MySqlConnection(connectionString))
            {
                IEnumerable<int> ids = bunifuCustomDataGrid1
                    .Rows[bunifuCustomDataGrid1.CurrentRow.Index]
                    .Cells
                    .Select(x => Convert.ToInt32(x.Value));
    
                string sql = $"DELETE FROM bookdb.book WHERE BookID IN ({string.Join(", ", ids)})";
    
                mysqlCon.Open();
                MySqlCommand cmd = new MySqlCommand(sql, mysqlCon);
    
                cmd.ExecuteNonQuery();
    
                mysqlCon.Close();
                GridFill();
            }
    
            MessageBox.Show("DOne");
    

    【讨论】:

    • 如果你不使用Parameters,请注意这里的sql注入,int应该不是问题
    • 我试过这段代码。但我在 .Select 中出现红线错误...我想知道为什么。
    • 您可能需要一些额外的代码来验证每个单元格的值,以确保它可以转换为整数
    猜你喜欢
    • 1970-01-01
    • 2016-11-08
    • 1970-01-01
    • 2019-02-07
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多