C# C:“如何处理”;自我参照”;对于DataGridView中的表?

C# C:“如何处理”;自我参照”;对于DataGridView中的表?,c#,data-binding,datagridview,C#,Data Binding,Datagridview,情况: 在我的数据库中有一个表,其中的记录可以引用同一表中的其他记录。每个记录都有一个唯一的数字ID(自动ID列)和一个可为空的列IDRef,其中可能包含要引用的记录的ID 现在,在我的C#Windows窗体应用程序中,我使用DataGridView允许用户编辑表中的记录。他可以添加、编辑或删除项目。我有一个类型化的数据集来保存数据,还有一个相应的TableAdapter来从数据库加载数据并执行更新。DataGridView绑定到使用类型化数据集作为其数据源的BindingSource 对于ID

情况:

在我的数据库中有一个表,其中的记录可以引用同一表中的其他记录。每个记录都有一个唯一的数字ID(自动ID列)和一个可为空的列
IDRef
,其中可能包含要引用的记录的ID

现在,在我的C#Windows窗体应用程序中,我使用DataGridView允许用户编辑表中的记录。他可以添加、编辑或删除项目。我有一个类型化的数据集来保存数据,还有一个相应的TableAdapter来从数据库加载数据并执行更新。DataGridView绑定到使用类型化数据集作为其数据源的BindingSource

对于
IDRef
列,我添加了一个ComboBox列,该列从与DataGridView本身相同的BindingSource填充其值。这意味着组合框始终是最新的记录数

问题:

我正在DataGridView中显示
ID
列。通过单击DataGridView的相应行添加新行时,ID值将自动填充为负值。只有在使用TableAdapter将更改持久化到数据库后,才能计算最终的auto ID值

现在,当我下拉
IDRef
列的组合框时,我可以选择以前存在的记录(例如101、102等),但也可以选择上次更新数据库后添加的记录(例如-1、-2、-3)

现在:在我使用TableAdapter的
Update
方法将更改持久化到数据库后,这些负ID不再存在-我正在引用不存在的记录(在我的情况下,这会导致外键约束错误)

解决方案?

我所做的是:

  • 对ComboBox列使用第二个DataSet和BindingSource
  • 添加一个“应用”按钮,使用TableAdapter更新对数据库的更改
  • 将数据重新读取到绑定到ComboBox列的第二个数据集中
这确保用户只能通过按“应用”按钮选择已持久化到数据库的值

有没有比使用DataGridView控件在表中处理此类“自引用”更优雅的方法


编辑:更改标记以更好地适应主题

使用两个不同的表时,负ID问题通过关系解决,编辑其属性并将其设置为具有级联更新的外键

我希望这也能用于自引用,但这很棘手

另一方面,我认为您应该为combobox使用不同的BindingSource(到同一个表)(或者不使用BindingSource进行绑定)


请注意,您也有一些其他可用的工具,如Adapter.Update(dataRow)

是的,目前我有第二个数据集和BindingSource用于组合。这工作得很好-只是我必须按下“应用”按钮,然后才能选择任何内容。这就是为什么我想知道是否有更优雅的方法。