如何删除GridView多选行并同步更新数据库对应数据
DataGridView选中多行同步删除数据库数据实现方案
核心逻辑顺序:先收集选中行对应的唯一主键 → 执行数据库删除 → 数据库操作成功后再移除界面行,顺序不能反,避免数据不一致。
原有代码问题说明
- 直接拼接SQL字符串存在SQL注入风险,且用
Supplier_name作为删除条件容易因为重名误删数据 - DELETE属于写操作,不需要用
MySqlDataReader读取数据,应该用ExecuteNonQuery()执行并获取受影响行数 - 遍历
SelectedRows时如果直接正序通过索引删行,会因为行集合动态变化导致索引错乱、删错数据
完整实现代码
private void btnDelete_Click(object sender, EventArgs e) { // 提前收集所有选中行的主键值,避免遍历过程中行集合变动出错 // 注意:把Supplier_id替换成你tb_supplier_list表实际的主键字段名 List<int> needDeleteIds = new List<int>(); foreach (DataGridViewRow row in DGV1.SelectedRows) { // 跳过未提交的新增空行 if (row.IsNewRow) continue; int id = Convert.ToInt32(row.Cells["Supplier_id"].Value); needDeleteIds.Add(id); } if (needDeleteIds.Count == 0) { MessageBox.Show("请先选中需要删除的行数据"); return; } // 构造参数化批量删除SQL,避免注入 string paramPlaceholders = string.Join(",", needDeleteIds.Select((_, idx) => $"@delId{idx}")); string deleteSql = $"DELETE FROM tb_supplier_list WHERE Supplier_id IN ({paramPlaceholders})"; // using会自动释放数据库连接、命令对象资源,不需要手动释放 using (MySqlConnection conn = new MySqlConnection(mainconn)) { using (MySqlCommand cmd = new MySqlCommand(deleteSql, conn)) { // 逐个添加SQL参数 for (int i = 0; i < needDeleteIds.Count; i++) { cmd.Parameters.AddWithValue($"@delId{i}", needDeleteIds[i]); } try { conn.Open(); int affectCount = cmd.ExecuteNonQuery(); conn.Close(); if (affectCount > 0) { // 数据库删除成功后,倒序移除界面选中行,避免索引错位 for (int i = DGV1.SelectedRows.Count - 1; i >= 0; i--) { if (!DGV1.SelectedRows[i].IsNewRow) { DGV1.Rows.Remove(DGV1.SelectedRows[i]); } } MessageBox.Show($"成功删除{affectCount}条供应商数据"); } else { MessageBox.Show("删除失败,未匹配到对应数据库记录"); } } catch (Exception ex) { MessageBox.Show($"删除出错:{ex.Message}"); if (conn.State == ConnectionState.Open) conn.Close(); } } } }
关键注意点
- 必须用表的主键(唯一不重复的字段)作为删除匹配条件,不要用名称这类可重复的字段,防止误删
- 如果你的DataGridView是直接绑定DataTable等数据源的,数据库删完之后直接重新调用绑定方法刷新数据源,比手动删行更不容易出错
- 倒序删除界面行是核心细节:正序删除时,每删一行后面的行索引会自动减1,会出现漏删、索引越界的问题
- 所有数据库操作建议加异常捕获,避免连接出错时程序直接崩溃
内容的提问来源于stack exchange,提问作者Philipe
相关产品推荐
相关产品推荐

