我有一个带有位列的 DataGridView,它显示为一个复选框。该列的名称为“IsDefault”,表示如果选中此单元格,则 DataTable 中此列中的所有其他单元格都应取消选中(仅允许此列中的 1 个单元格为默认值)。
我设法通过处理 DataGridView 的 CellContentClick 事件中的更改来使这种行为起作用,即:
private void ViewIconsDataGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex == -1 || e.ColumnIndex == -1)
return;
DataTable table = ViewIconsDataGrid.DataSource as DataTable;
DataGridViewCell cell = ViewIconsDataGrid.Rows[e.RowIndex].Cells[e.ColumnIndex];
Guid rowID = (Guid)ViewIconsDataGrid.Rows[e.RowIndex].Cells["ID"].Value;
if (cell.GetType() == typeof(DataGridViewCheckBoxCell))
{
DataGridViewCheckBoxCell checkBoxCell = cell as DataGridViewCheckBoxCell;
bool value = (bool)checkBoxCell.EditedFormattedValue, previous = (bool)checkBoxCell.Value;
if (value != previous)
{
if (value == true)
{
Guid currentDefault;
if(MyIcons.Defaults.TryGetValue(MyGroupID, out currentDefault))
{
DataRow [] rows = table.Select("ID = '" + currentDefault.ToString() + "'");
if(rows.Length == 1)
{
rows[0]["IsDefault"] = false;
}
}
}
ViewIconsDataGrid.EndEdit(); table.AcceptChanges();
}
}
}
现在,显然我正在尝试更改同一 DataTable 中的两条记录。首先我希望 DataGridView 发生变化(当用户更改复选框的状态时),然后我在 DataTable 上进行另一项更改以取消选中已经进行检查的任何行,希望它将传播到 DataGridView。当然,我需要将这两项更改都提交到数据库。
这是我的数据库“更新”代码,它是一种通用的,即我传入整个表的选择查询和要更新的数据表:
using (SqlConnection connection = new SqlConnection(ConfigurationManager.AppSettings["Connection"]))
{
connection.Open();
using (SqlDataAdapter adapter = new SqlDataAdapter(MyQuery, connection))
{
adapter.InsertCommand = new SqlCommandBuilder(adapter).GetInsertCommand();
adapter.DeleteCommand = new SqlCommandBuilder(adapter).GetDeleteCommand();
adapter.UpdateCommand = new SqlCommandBuilder(adapter).GetUpdateCommand();
adapter.Update(MyTable);
}
}
所以,问题是当我在进行这些更改后尝试更新表时出现异常:“并发冲突:UpdateCommand 影响了预期的 1 条记录中的 0 条。”。如果没有现有的默认值,则只会更新一条记录,一切都很好。
谁能发现我的错误,或者找到一种更简单的方法来做到这一点?
编辑 1:在上面的片段中,MyQuery如下所示:
@"SELECT * From Picture WHERE ID_Group = '{0}' AND Deleted = 0 ORDER BY Created DESC
{0} 是我正在更新的图片组的 guid,即选择查询提供图片表中属于该组成员的所有记录。