关于自动递增 ID,数据库和数据集未同步
Database and DataSet are not synced regarding auto incrementing ID
我使用 Visual Studio 和一个包含两个字段的 table 构建了一个数据库 (Microsoft SqlServerCe.4.0):
- id: int, 主键, not null, unique, no default value, identity
- 名义上,我们并不关心这个
然后我构建了一个包含此 table 作为数据表的数据集,并且我有一个像这样的数据适配器:
marque_adapter = factory.CreateDataAdapter();
command = connection.CreateCommand();
command.CommandText = "SELECT * FROM " + DB_TABLE_MARQUE + ";";
marque_adapter.SelectCommand = command;
command = connection.CreateCommand();
command.CommandText = "UPDATE " + DB_TABLE_MARQUE + " SET nom = @nom WHERE id = @id;";
CreateAndAddParameterFromSource(command, "id", "id");
CreateAndAddParameterFromSource(command, "nom", "nom");
marque_adapter.UpdateCommand = command;
command = connection.CreateCommand();
command.CommandText = "DELETE " + DB_TABLE_MARQUE + " WHERE id = @id;";
CreateAndAddParameterFromSource(command, "id", "id");
marque_adapter.DeleteCommand = command;
command = connection.CreateCommand();
command.CommandText = "INSERT INTO " + DB_TABLE_MARQUE + " (nom) VALUES (@nom);";
CreateAndAddParameterFromSource(command, "nom", "nom");
marque_adapter.InsertCommand = command;
//...
data = new DataSet();
marque_adapter.Fill(data, DB_TABLE_MARQUE);
当我尝试插入新行时出现问题。
我愿意 :
- table.NewRow()
- 设置"nom"字段
- table.Rows.Add(新行)
- adapter.Update(数据集,table名称)
如果我不做任何其他事情,稍后当我尝试获取该行的 ID 时会遇到问题(我猜它会将其设置在上述四个指令之间的某个位置)。
我期待 DataTable 负责生成一个,但是 ...
所以我尝试提醒 DataTable 处理自动递增:
idColumn.Unique = true;
idColumn.AutoIncrement = true;
现在它第一次工作了,但是当我第二次 运行 程序时,它又从一个开始计数,我被告知 ID 应该是唯一的。如果我删除数据库(Visual 制作的 sdf 文件的副本),或者如果我使用 Visual 手动删除行,第一次 运行 很好,之后我得到同样的错误。
真正的问题是当我尝试保存我的数据集时,尤其是在添加新行时(选择、更新、删除都可以)。
显然,当涉及到 DataTable 和数据库时,我不知道如何管理主键(单独使用 datatable 就可以)。
特别是要同步这两个 ...
我错过了什么?
我很确定我误解了什么。
根据MSDN,
Bydefault, AcceptChanges
is called implicitly after an update, and the original values in the row, which may have been AutoIncrement values assigned by ADO.NET, are lost.
因此您需要创建一个策略来合并 AutoIncremented 值通过 ADO 或从 Sql 取回递增的 Id 作为输出参数,然后按照此 MSDN [=13] 中的指示合并标识列值=].
我使用 Visual Studio 和一个包含两个字段的 table 构建了一个数据库 (Microsoft SqlServerCe.4.0):
- id: int, 主键, not null, unique, no default value, identity
- 名义上,我们并不关心这个
然后我构建了一个包含此 table 作为数据表的数据集,并且我有一个像这样的数据适配器:
marque_adapter = factory.CreateDataAdapter();
command = connection.CreateCommand();
command.CommandText = "SELECT * FROM " + DB_TABLE_MARQUE + ";";
marque_adapter.SelectCommand = command;
command = connection.CreateCommand();
command.CommandText = "UPDATE " + DB_TABLE_MARQUE + " SET nom = @nom WHERE id = @id;";
CreateAndAddParameterFromSource(command, "id", "id");
CreateAndAddParameterFromSource(command, "nom", "nom");
marque_adapter.UpdateCommand = command;
command = connection.CreateCommand();
command.CommandText = "DELETE " + DB_TABLE_MARQUE + " WHERE id = @id;";
CreateAndAddParameterFromSource(command, "id", "id");
marque_adapter.DeleteCommand = command;
command = connection.CreateCommand();
command.CommandText = "INSERT INTO " + DB_TABLE_MARQUE + " (nom) VALUES (@nom);";
CreateAndAddParameterFromSource(command, "nom", "nom");
marque_adapter.InsertCommand = command;
//...
data = new DataSet();
marque_adapter.Fill(data, DB_TABLE_MARQUE);
当我尝试插入新行时出现问题。 我愿意 :
- table.NewRow()
- 设置"nom"字段
- table.Rows.Add(新行)
- adapter.Update(数据集,table名称)
如果我不做任何其他事情,稍后当我尝试获取该行的 ID 时会遇到问题(我猜它会将其设置在上述四个指令之间的某个位置)。 我期待 DataTable 负责生成一个,但是 ...
所以我尝试提醒 DataTable 处理自动递增:
idColumn.Unique = true;
idColumn.AutoIncrement = true;
现在它第一次工作了,但是当我第二次 运行 程序时,它又从一个开始计数,我被告知 ID 应该是唯一的。如果我删除数据库(Visual 制作的 sdf 文件的副本),或者如果我使用 Visual 手动删除行,第一次 运行 很好,之后我得到同样的错误。
真正的问题是当我尝试保存我的数据集时,尤其是在添加新行时(选择、更新、删除都可以)。
显然,当涉及到 DataTable 和数据库时,我不知道如何管理主键(单独使用 datatable 就可以)。 特别是要同步这两个 ...
我错过了什么? 我很确定我误解了什么。
根据MSDN,
Bydefault,
AcceptChanges
is called implicitly after an update, and the original values in the row, which may have been AutoIncrement values assigned by ADO.NET, are lost.
因此您需要创建一个策略来合并 AutoIncremented 值通过 ADO 或从 Sql 取回递增的 Id 作为输出参数,然后按照此 MSDN [=13] 中的指示合并标识列值=].