情况:
在我的数据库中,我有一个表,其中的记录可以引用同一个表中的其他记录。每条记录都有一个唯一的数字 ID(自动 ID 列)和一个可为空的列 IDRef
,其中可能包含要引用的记录的 ID。
现在,在我的 C# Windows 窗体应用程序中,我使用 DataGridView 来允许用户编辑表中的记录。他可以添加、编辑或删除项目。我有一个类型化的 DataSet 来保存数据,还有一个相应的 TableAdapter 从数据库加载数据并执行更新。 DataGridView 绑定(bind)到使用类型化 DataSet 作为其数据源的 BindingSource。
对于 IDRef
列,我添加了一个 ComboBox 列,它从与 DataGridView 本身相同的 BindingSource 填充其值。这意味着 ComboBox 始终与记录数保持同步。
问题:
我在 DataGridView 中显示 ID
列。通过单击 DataGridView 的相应行来添加新行时,ID 值会自动填充为负值。只有在使用 TableAdapter 将更改持久化到数据库后,才会计算最终的自动 ID 值。
现在,当我下拉IDRef
列的 ComboBox 时,我可以选择以前存在的记录(例如 101、102 等),但我也可以选择已添加的记录在上次更新数据库之后(例如 -1、-2、-3)。
现在:在我使用 TableAdapter 的 Update
方法将更改保存到数据库后,这些负 ID 不再存在 - 我引用了不存在的记录(在我的例子中,这导致外键约束错误)。
解决方案?
我所做的是:
- 为 ComboBox 列使用第二个 DataSet 和 BindingSource
- 添加一个“应用”按钮,使用 TableAdapter 将更改更新到数据库
- 将数据重新读入绑定(bind)到 ComboBox 列的第二个 DataSet
这确保用户只能通过按下“应用”按钮来选择已保存到数据库中的值。
有没有比使用 DataGridView 控件处理表格内的这种“自引用”更优雅的方法?
编辑:更改标签以更适合主题
最佳答案
当使用两个不同的表时,负 ID 问题由关系解决,编辑它的属性并将其设置为具有级联更新的外键。
我希望这也适用于自引用,但这很棘手。
另外,我认为您应该为组合框(或不带 BindingSource 的绑定(bind))设置不同的 BindingSource(到同一个表)。
请注意,您还有一些其他可用的工具,例如 Adapter.Update (dataRow)
关于C#:如何处理 DataGridView 中的表的 "self-references"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/969868/