VS2022 VB WinForm绑定源过滤触发ID唯一约束异常问题
环境
- VS2022 PRO
- VB WinForm App
- .NET 4.7.2
问题重现
下拉框(Status)选中值变更时,通过SQL TableAdapter更新只读DataGridView(TableAdapter已开启ClearBeforeFill),对BindingSource应用过滤流程正常,但选择无对应记录的状态时,抛出异常:
System.Data.ConstraintException: Column 'ID' is constrained to be unique. Value '6' is already present
已在过滤前调用Me.VwConsumerProvidersAllBindingSource.RemoveFilter()清除过滤,但问题依旧,且此前VS2019 + .NET 4.6.1环境下无此问题。
解决方案
1. 手动强制清空DataTable后再Fill
虽然TableAdapter默认开启ClearBeforeFill,但.NET 4.7.2对DataSet的处理逻辑可能存在差异,导致清空操作未生效。在Fill前手动清空DataTable:
' 先清空DataTable确保无残留数据 Me.DsConsProv.vwConsumerProvidersAll.Clear() Me.VwConsumerProvidersAllTableAdapter.Fill(Me.DsConsProv.vwConsumerProvidersAll) Me.VwConsumerProvidersAllBindingSource.RemoveFilter() ' 构造过滤字符串 Me.VwConsumerProvidersAllBindingSource.Filter = FilterString
2. 重置BindingSource的数据源绑定
尝试在Fill前后解绑/重新绑定BindingSource,避免旧数据缓存:
' 临时解绑数据源 Me.VwConsumerProvidersAllBindingSource.DataSource = Nothing ' 填充数据 Me.VwConsumerProvidersAllTableAdapter.Fill(Me.DsConsProv.vwConsumerProvidersAll) ' 重新绑定 Me.VwConsumerProvidersAllBindingSource.DataSource = Me.DsConsProv.vwConsumerProvidersAll ' 移除旧过滤并应用新过滤 Me.VwConsumerProvidersAllBindingSource.RemoveFilter() Me.VwConsumerProvidersAllBindingSource.Filter = FilterString
3. 填充时临时禁用DataSet约束
在Fill操作前后临时关闭约束检查,避免填充过程中触发约束冲突(注意填充完成后要重新开启):
Me.DsConsProv.EnforceConstraints = False Me.VwConsumerProvidersAllTableAdapter.Fill(Me.DsConsProv.vwConsumerProvidersAll) Me.DsConsProv.EnforceConstraints = True ' 后续过滤操作 Me.VwConsumerProvidersAllBindingSource.RemoveFilter() Me.VwConsumerProvidersAllBindingSource.Filter = FilterString
4. 排查隐藏的数据修改逻辑
检查是否存在其他组件/事件(如DataGridView的CellValueChanged、BindingSource的ListChanged)在后台修改了DataTable数据,导致ID重复。可以在Fill前后打印DataTable的行数和ID值,确认数据是否真的被清空:
Debug.WriteLine($"Fill前行数: {Me.DsConsProv.vwConsumerProvidersAll.Rows.Count}") Me.VwConsumerProvidersAllTableAdapter.Fill(Me.DsConsProv.vwConsumerProvidersAll) Debug.WriteLine($"Fill后行数: {Me.DsConsProv.vwConsumerProvidersAll.Rows.Count}")
5. 检查DataTable的约束配置
打开DataSet设计器,确认vwConsumerProvidersAll表的ID列唯一约束是否重复添加,或者约束配置是否正确。若存在多余约束,删除后重新生成TableAdapter。
内容的提问来源于stack exchange,提问作者Guarandingo

