c# - 检索身份列 ADO.net 时出现问题
问题描述
当多个用户同时工作时,我的代码出现问题。它向我显示了一个错误:
'Column 'id' 被限制为唯一。值“9”已经存在。
我试图在一个小代码上模拟它,这样你就可以理解这个问题。
假设我们有一个数据库,其中有一个名为 Table1 的表
CREATE TABLE table1 (
[id] int not null IDENTITY(1,1) PRIMARY KEY,
[Name] nvarchar(max) not null,
);
我有这个简单的控制台应用程序:
static void Main(string[] args)
{
const string connectionString = "Server=.;Database=Test;User Id=sa;Password=;";
using var connection = new SqlConnection(connectionString);
connection.Open();
using var adapter = new SqlDataAdapter("Select * from [Table1]", connection)
{
InsertCommand = new SqlCommand("Insert into Table1 ([Name]) values(@NameParam); Select [ID],[Name] from [Table1] where [id]= SCOPE_IDENTITY();",connection)
{
CommandType = CommandType.Text
}
};
adapter.InsertCommand.Parameters.Add(new SqlParameter("@NameParam", SqlDbType.NVarChar, 40, "Name"));
adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.Both;
// MissingSchemaAction adds any missing schema to
// the DataTable, including identity columns
adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
adapter.RowUpdated += Adapter_RowUpdated;
var table = new DataTable();
adapter.Fill(table);
// this insert command simulates another user on the network inserted a row
var anotherInsertCommand = new SqlCommand("Insert into Table1 ([Name]) values('Test1');",connection);
anotherInsertCommand.ExecuteNonQuery();
DataRow newRow = table.NewRow();
newRow["Name"] = "test2";
table.Rows.Add(newRow);
DataRow newRow1 = table.NewRow();
newRow1["Name"] = "test3";
table.Rows.Add(newRow1);
DataTable changedData = table.GetChanges();
adapter.Update(changedData);
table.Merge(changedData);
table.AcceptChanges();
}
private static void Adapter_RowUpdated(object sender, SqlRowUpdatedEventArgs e)
{
// If this is an insert, then skip this row.
if (e.StatementType != StatementType.Insert) return;
if (e.Status == UpdateStatus.ErrorsOccurred)
{
// here it will show an error that the retrieved Identity column is already exist on the dataTable. Because we still didn't update the second row
throw e.Errors;
}
e.Status = UpdateStatus.SkipCurrentRow;
}
现在的问题是我在说明应用程序时填写了我的数据表,因此数据表将没有行,只有模式。
后来另一个使用同一应用程序的用户在数据库中插入一行。但我的 dataTable 不会知道这一行。
之后,我在 dataTable 上插入两行并尝试检索 Identity 列值。但它向我显示了这个错误。
有没有人有一个简单快速的方法来解决这个问题。比如禁用约束什么的。我不知道。
注意:这里解释了我检索身份值的方式,我按照他们的解释做了。如何检索身份值
解决方案
可能的解决方法是
SELECT MAX(Id) FROM Table
在插入之前使用 for eg + 1 来获取最后插入的 ID。在 INSERT 你可以做SET IDENTITY_INSERT yourTable ON INSERT INTO yourTable (IdentityColumn, col2) VALUES (Identity, col2value ) SET IDENTITY_INSERT yourTable OFF
尝试将 DataTable 中身份列的 AutoIncrementSeed 和 AutoIncrementStep 属性设置为 -1。
这是他们说的文档:“您可以使用 DataRow 类的 ItemArray 属性并传入一个值数组来创建一个新行。对于 AutoIncrement 设置为 true 的列来说,这是一个潜在的问题。”我知道您没有使用 ItemArray 但也许您正在处理类似的事情。
推荐阅读
- c# - C# NullReferenceException 但没有什么是空的
- python-3.x - Pyinstaller - 如何捆绑 imagemagick , Tesserocr
- r - 根据任意 2 个条件为真创建一个新变量
- r - R:解开图表
- powershell - 等待每个 Powershell
- github - 如何在单页应用程序中保存 GitHub 访问令牌?
- r - KatRisk 软件和 R studio 软件的问题
- amazon-web-services - 每次我停止一个 EC2 实例时,都会创建另一个实例
- python - 从熊猫数据框中删除重复的列值
- python - 是否有一个分类编码器允许我指定起点(即不是 0)?或使特定值不受限制?