【问题标题】:Dataset does not reflect new primary key after insert插入后数据集不反映新的主键
【发布时间】:2025-12-01 13:35:01
【问题描述】:

这是我在这里的第一个问题,请原谅我的演讲风格。

我有一个 MySQL 表 categories,其中包含以下列:

  • c_id (自动递增)
  • c_code
  • c_name

这是我想要做的;

  • 数据集包含一个表 - categories
  • 向数据集添加一行(新类别)
  • 使用mysqldataadaptorupdate()方法更新数据库
  • 在 datagridview 中查看数据集条目

问题是在我插入新行后,我的数据集的相关行没有显示最后插入的主键(自动生成的主键)。但它显示了价值。

这是我添加新行的代码

var dr = ds.Tables["categories"].NewRow();
    dr["c_code"] = "tst123";
    dr["c_name"] = "123tdt";
ds.Tables["categories"].Rows.Add(dr);

这是我更新数据库的代码

adp.Update(ds.Tables[tempTableName]);

最后这就是我如何查看数据集 SOON AFTER 以上行

dataGridView1.DataSource = ds.Tables["categories"];

问题:
在 gridview 中只有 c_codec_name 出现在那里。

如何获取最后插入的id 到数据集?

【问题讨论】:

  • ADO.NET DataSetDataTable 在插入后不会自动重新查询数据库 - 这就是为什么您没有取回新插入的 ID。您需要从INSERT 返回ID(例如通过使用存储过程或类似的东西),或者您需要重新执行查询以获取数据,以便从数据库中读取数据再次表 - 新插入的 ID 在其中。
  • 你应该把它作为答案。那么我看起来就不会像一头免费的驴了:D
  • 谢谢 marc_s。认为我需要一个存储过程,因为重新加载会导致很多不必要的开销。 (重复)

标签: c# dataset sql-update auto-increment


【解决方案1】:

我猜你必须做一个新的 adp.Fill(ds) 来获取 ID。您只提供 c_code 和 c_name。因此,c_code 和 c_name 是网格中唯一填充的列。 adp.Update 更新您的数据库,由于显而易见的原因,它不会在更新后重新加载整个数据集。

【讨论】:

  • 感谢 WozzeC,感谢您的想法。计划使用 marc_s 方法。很快就会在这里更新
【解决方案2】:

这对我有用: 它在 VB 中,但您可以看到发生了什么。

mySQLdataAdapter.Update(myDataSet, table)
mySQLcommand.CommandText = "Select Last_Insert_ID();"
lastInsertID = dc.ExecuteScalar()

在 mysql 适配器更新后立即运行此代码会提供最后插入的 ID,即使我正在使用数据集。

【讨论】:

    【解决方案3】:

    可以使用DataAdapter的RowUpdated事件查询最后插入的ID,更新当前行:

    ...
    adp.RowUpdated += DataAdapter_RowUpdated; // Add this once to your DataAdapter
    adp.Update(ds.Tables[tempTableName]);
    ...
    
    private void DataAdapter_RowUpdated(object sender, MySqlRowUpdatedEventArgs e)
    {
      if (e.StatementType == StatementType.Insert)
      {
         string sql = "select last_insert_id()";
         MySqlCommand cmd = new MySqlCommand(sql, e.Command.Connection);
         e.Row["c_id"] = cmd.ExecuteScalar();
      }
    }
    

    【讨论】: