从数据库中删除选定的数据表行

Posted

技术标签:

【中文标题】从数据库中删除选定的数据表行【英文标题】:Delete selected datatable row from database 【发布时间】:2014-11-05 10:07:10 【问题描述】:

我在 C# 的 DataGridView 中有一个数据表。我用从 mysql 数据库获得的值填充了这个表。现在,一旦我在 WinForm 端的数据表中添加任何新值,它就可以成功检索数据库表并添加到它。这是用于此目的的代码:

dbDataset.RowChanged += new DataRowChangeEventHandler(Row_Changed); // dbDataset is my datatable name

    private static void Row_Changed(object sender, DataRowChangeEventArgs e)
    
            // here sda is my MySqlDataAdapter
            try
            
                MySqlCommandBuilder cmdb = new MySqlCommandBuilder(sda);
                dbDataset.GetChanges();
                dbDataset.GetChanges(DataRowState.Added);
                dbDataset.GetChanges(DataRowState.Deleted);
                dbDataset.GetChanges(DataRowState.Detached);
                dbDataset.GetChanges(DataRowState.Modified);
                dbDataset.GetChanges(DataRowState.Unchanged);                    
                sda.Update(dbDataset);                
            
            catch (Exception ex)
            
                MessageBox.Show(ex.Message);
            
    

但是现在我发现当我想从表中删除任何一行时,例如我选择一行并按“删除”键,它会在屏幕上显示它已被删除,但是一旦我重新加载我的 WinForm,它仍然在那里。显然它没有从数据库中删除该选定的行。为此,经过一番搜索,我添加了以下部分:

dbDataset.RowDeleted += new DataRowChangeEventHandler(Row_Deleted);

    private static void Row_Deleted(object sender, DataRowChangeEventArgs e)
    
        dbDataset.AcceptChanges();
    

通过调试发现,当我按下“delete”键时,进入Row_Delete函数,然后进入Row_Changed函数,但抛出异常,说:

Additional information: Concurrency violation: the DeleteCommand affected 0 of the expected 1 records.

我搜索得到当前选择的行索引,这样我就可以使用 DataRow.delete 方法,例如:

CurrencyManager xCM = = (CurrencyManager)this.BindingContext[this.dataGridView1.DataSource, this.dataGridView1.DataMember];

Row_Deleted 函数中我添加了:

DataRowView xDRV = (DataRowView)xCM.Current;
DataRow xDR = ((DataRowView)xCM.Current).Row;
xDR.Delete();

但它给出了空异常,说dataGridView1的数据源不能为空。

有没有关于如何从数据库中删除所选行的想法?提前致谢。

【问题讨论】:

AcceptChanges 很棘手。它不会更新数据库上的任何内容。它只接受内存数据表上的更改。如果您调用它,则不会将任何内容写入数据库,因为每行的状态都将重置为未更改,并且已删除的行将从数据表中删除 那么我应该怎么做才能从数据库中删除呢? Row_Changed 事件中的代码应该可以工作(删除不需要的 GetChanges 调用)但是,我会在 button_click 事件(保存按钮)中编写该代码,而不是为每个更改的行执行它.如果我没记错的话,Update 调用会导致对 RowChanged 的​​递归调用。 确实很棘手 :) 我按照你说的做了,删除了 Row_Changed 函数中的所有 GetChanges 调用,然后只保留了 Row_Deleted 函数中的 dbDataset.AcceptChanges() 行。现在它按预期工作。谢谢。 我认为它起作用只是因为您在删除后进行了更改。使用 Update 调用对 RowChanged 的​​调用是使用更改更新数据库的调用。如果您只是删除一行而不进行任何其他更改,我认为您的行没有从数据库中删除。 【参考方案1】:

我将使用两种不同的方法进行更新。一个用于插入/更新,一个用于删除。 当您删除行时,框架将调用 RowDeleted 事件处理程序,而不是 RowChanged。

private static void Row_Changed(object sender, DataRowChangeEventArgs e)

    try
    
        MySqlCommandBuilder cmdb = new MySqlCommandBuilder(sda);
        sda.Update(dbDataset);                
    
    catch (Exception ex)
    
        MessageBox.Show(ex.Message);
    


private void Row_Deleted(object sender, DataRowChangeEventArgs e)

    try
    
        SqlCommandBuilder cmdb = new SqlCommandBuilder(da);
        da.Update(dt);                
    
    catch (Exception ex)
    
        Console.WriteLine(ex.Message);
    

您应该删除AcceptChanges 调用。根据 MSDN

当您在 DataSet 上调用 AcceptChanges 时,任何 DataRow 对象仍然 在编辑模式下成功结束他们的编辑。的 RowState 属性 每个 DataRow 也会发生变化;添加和修改的行变为未更改, 并删除已删除的行。

【讨论】:

以上是关于从数据库中删除选定的数据表行的主要内容,如果未能解决你的问题,请参考以下文章

删除数据表Vuetify上的选定行

在android的listview中删除选定的行

从数据网格视图和数据库中删除选定的行

如何从筛选数据表 (DT) 的选定行中获取数据?

根据数据绑定组合框中的选定项目从访问数据库中删除

引导表从选定行获取数据