使用TableAdapter.Update(DataRow)后同步数据库Identity Column至DataGridView
解决DataGridView插入后同步Identity真实值的问题
问题背景
通过DataGridView绑定DataTable插入数据时,采用逐行调用TableAdapter.Update(DataRow)的方式能正常插入数据,但DataTable的Identity列会显示临时值(-1、-2等),无法同步数据库生成的真实ID;而调用TableAdapter.Update(DataSet.DataTable)时,因自动执行了Select * from Datatable1 where (Column1_ID = SCOPE_IDENTITY())查询,可正常显示真实ID。现需保留逐行更新的方式,实现真实Identity值同步到DataGridView。
解决方案
核心思路是让TableAdapter的InsertCommand在插入数据后返回数据库生成的Identity值,再将该值更新到对应的DataRow中,最终同步到DataGridView。
步骤1:配置TableAdapter的InsertCommand
- 打开项目的DataSet设计器(双击你的
.xsd文件)。 - 找到
DataTable1对应的TableAdapter,直接编辑InsertCommand的命令文本。 - 修改Insert语句,在末尾添加
SELECT SCOPE_IDENTITY()获取刚插入行的Identity值,示例SQL:
INSERT INTO DataTable1 (Column2, Column3) VALUES (@Column2, @Column3); SELECT Column1_ID = SCOPE_IDENTITY();
注意:
Column1_ID替换为你的实际Identity列名;Column2、Column3替换为表中其他需要插入的字段。
- 为
InsertCommand添加输出参数:- 在
InsertCommand的参数集合中,添加参数(比如@Column1_ID),设置参数方向为Output,数据类型与Identity列一致(比如Int32),并映射到DataTable的Column1_ID列。
- 在
步骤2:修改逐行更新代码
在逐行更新时,执行插入后获取返回的真实Identity值,更新到DataRow并提交变更,最后刷新BindingSource同步到DataGridView:
Dim My_Datatable_Added As DataTable = DataSet1.DataTable1.GetChanges(DataRowState.Added) If My_Datatable_Added IsNot Nothing Then For Each My_Data_Row As DataRow In My_Datatable_Added.Rows ' 执行插入更新 Me.DataTable1TableAdapter.Update(My_Data_Row) ' 从InsertCommand的输出参数中获取真实Identity值 Dim realId As Integer = CInt(Me.DataTable1TableAdapter.InsertCommand.Parameters("@Column1_ID").Value) ' 更新DataRow的Identity列 My_Data_Row("Column1_ID") = realId ' 标记该行变更已提交,清除临时状态 My_Data_Row.AcceptChanges() Next ' 刷新BindingSource,让DataGridView立即显示真实ID DataTable1TableBindingSource.ResetBindings(False) End If
补充说明
- 确保
DataTable的Identity列设置了AutoIncrement = True、AutoIncrementSeed = -1、AutoIncrementStep = -1,这样插入时会自动生成临时负数值。 SCOPE_IDENTITY()仅返回当前会话当前作用域内生成的最后一个Identity值,能避免其他会话插入数据导致的ID混乱,是获取插入行真实ID的最优方式。
内容的提问来源于stack exchange,提问作者Imad
相关产品推荐
相关产品推荐

