C# 使用数据适配器更新记录时获取并发错误

C# 使用数据适配器更新记录时获取并发错误,c#,.net,datatable,ado.net,dataadapter,C#,.net,Datatable,Ado.net,Dataadapter,这是我的桌子: Student:StudentId int PK自动递增,名称varchar(20) 当我试图更新上次添加的记录时,我遇到错误: 错误:并发冲突:UpdateCommand影响了预期的1条记录中的0条。 这是我的代码: using (var connection = new SqlConnection("MyConnectionstring")) { connection.Open(); Sq

这是我的桌子:

Student
StudentId int PK自动递增,名称varchar(20)

当我试图更新上次添加的记录时,我遇到错误:

错误
并发冲突:UpdateCommand影响了预期的1条记录中的0条。

这是我的代码:

using (var connection = new SqlConnection("MyConnectionstring"))
            {
                connection.Open();
                SqlDataAdapter adapter = new SqlDataAdapter();
                SqlCommandBuilder builder = new SqlCommandBuilder(adapter);

                adapter.SelectCommand = new SqlCommand("select * from Student", connection);


                DataTable dt = new DataTable();
                adapter.Fill(dt);

                DataRow row = dt.NewRow();
                row["Name"] = "Abc";
                dt.Rows.Add(row);
                var addedRecords = dt.GetChanges(DataRowState.Added);
                adapter.Update(dt);
                dt.AcceptChanges();
                DataRow lastRow = dt.Rows[dt.Rows.Count - 1];

                row["Name"] = "Pqr";
                adapter.Update(dt); //Error Here
                connection.Close();
            }  

有人能告诉我为什么会发生这种情况,以及解决这个问题的方法是什么吗?

当您进行第一次更新时,该行会写入数据库,并且它会根据
自动增量获得一个主键。但是,
DataTable
中的行并不反映更改的ID。因此,当您尝试执行第二次更新时,它找不到要更新的行(数据表中的ID与数据库中的ID不匹配)。因此,会出现并发错误

这就是为什么,为了将ID放入
数据表
,您需要在执行第二次更新之前刷新
数据表
的内容

要刷新
数据表
,请调用:

adapter.Fill()

有关详细信息,请阅读。

当您执行第一次更新时,该行将写入数据库,并根据
自动增量获得一个主键。但是,
DataTable
中的行并不反映更改的ID。因此,当您尝试执行第二次更新时,它找不到要更新的行(数据表中的ID与数据库中的ID不匹配)。因此,会出现并发错误

这就是为什么,为了将ID放入
数据表
,您需要在执行第二次更新之前刷新
数据表
的内容

要刷新
数据表
,请调用:

adapter.Fill()
有关详细信息,请阅读。

如MSDN主题中所述,由命令生成器生成的自动命令不会检索插入记录的标识字段:

您可能希望将输出参数映射回数据集的更新行。一个常见的任务是从数据源检索自动生成的标识字段或时间戳的值。默认情况下,DbCommandBuilder不会将输出参数映射到更新行中的列。在这种情况下,必须显式指定命令

看看主题,事实证明基本上您需要手动生成insert命令

以下是如何为表执行此操作(请参见代码中的注释):

如MSDN主题中所述,命令生成器生成的自动命令不会检索插入记录的标识字段:

您可能希望将输出参数映射回数据集的更新行。一个常见的任务是从数据源检索自动生成的标识字段或时间戳的值。默认情况下,DbCommandBuilder不会将输出参数映射到更新行中的列。在这种情况下,必须显式指定命令

看看主题,事实证明基本上您需要手动生成insert命令

以下是如何为表执行此操作(请参见代码中的注释):



您修改了同一行两次。这是故意的吗?或者你打算修改最后一行吗?我想,如果你想修改最后一行,int lastrow=dt.Rows.Count-1;行[lastrow][“名称”]=“pqr”@PanagiotisKanavos:首先我想添加记录,然后我想更新最近添加的记录,实际上我正试图理解rowstate的过程,这就是我为什么要这么做的原因this@sowjanyaattaluri:我想修改datatable和in-database table中的最后一行需要编写查询以修改in-database table。您修改了同一行两次。这是故意的吗?或者你打算修改最后一行吗?我想,如果你想修改最后一行,int lastrow=dt.Rows.Count-1;行[lastrow][“名称”]=“pqr”@PanagiotisKanavos:首先我想添加记录,然后我想更新最近添加的记录,实际上我正试图理解rowstate的过程,这就是我为什么要这么做的原因this@sowjanyaattaluri:我想修改datatable和in-database table中的最后一行,需要在database table中编写要修改的查询。这就是原因吗在更新我的最后一条记录期间,ado.net无法找到最后一条记录的Id,因为该记录已提交到数据库中,但仍不在datatable中,正如@Amy??Yes所指出的。这是数据库自动生成的ID列的特定问题。只有在insert(add new)时才会发生这种情况,并且生成的值必须以某种方式读回(因为update、delete等确实需要该id才能将表记录与相应的数据库记录相匹配)。很可能我可以,但请填写另一个问题,这样我(或其他人)就可以回答它。嗯,您必须绑定命令中使用的所有参数,例如,
updateCommand.parameters.Add(“@Id”,SqlDbType.Int,0,“StudentId”)。不要忘记将您创建的命令分配给
adapter.UpdateCommand
。您应该问问自己是否要手动创建UpdateCommand。正如我在回答中提到的,只需要InsertCommand,其他命令可以由命令生成器处理。这就是为什么在更新我的最后一条记录时ado.net无法找到最后一条记录的Id的原因,因为该记录在数据库中提交,但仍然不在datatable中,正如@Amy??Yes所指出的。这是数据库自动生成的ID列的特定问题。只有当insert(add new)和生成的值必须以某种方式读回时才会发生这种情况(因为update、delete等确实需要该id才能将表记录与相应的数据库记录匹配)。我很可能可以,但请填写另一个问题,因此我(o