ADO.net 将新行插入到具有 IDENTITY 列的 table 中,如何正确执行此操作?

ADO.net insert a new row into a table that has a IDENTITY column, how to do that correctly?

我在 SQL 服务器实例中有一个 table,它看起来像:

IF OBJECT_ID(N'dbo.employees', N'U') IS NOT NULL
    DROP TABLE dbo.Employees;
GO

CREATE TABLE dbo.employees
(
 id INT IDENTITY
        PRIMARY KEY,
 name NVARCHAR(20),
 age TINYINT,
 birthday DATETIME
);

我正在学习 ADO.net,我想在 table 中插入一个新行。我的代码如下:

string connectionString = @"Server=.\sql2014;Database=Test;Trusted_connection=True;";
SqlConnection connection = new SqlConnection(connectionString);

SqlDataAdapter adapter = new SqlDataAdapter("select * from dbo.employees", connection);
new SqlCommandBuilder(adapter);

DataSet dataSet = new DataSet();
adapter.Fill(dataSet, "employees");

dataSet.Tables[0].Constraints.Add("pk_employees", dataSet.Tables[0].Columns[0], true);

DataRow row = dataSet.Tables[0].NewRow();
row["id"] = 1;
row["name"] = "Hi";
row["age"] = 33;
row["birthday"] = "1982-10-09";

dataSet.Tables[0].Rows.Add(row);
adapter.Update(dataSet.Tables[0]);

MessageBox.Show("Inserted!");

table 的 id 列是 IDENTITY 属性,这意味着它的值将自动生成。但是,我必须将 row["id"] 设置为某个整数值,否则会出现错误 "the id column doesn't all null"。当我使用 SQL Server profiler 捕获执行的 SQL 时,我发现执行的 SQL 看起来像:

exec sp_executesql N'INSERT INTO [dbo].[employees] ([name], [age], [birthday])
VALUES (@p1, @p2, @p3)',
N'@p1 nvarchar(4),@p2 tinyint,@p3 datetime',@p1=N'Hi',@p2=33,@p3='1982-10-09 00:00:00'

我想知道,在这样的 table 中插入数据的正确方法是什么?如果 table 已经有一些行并且它的最大 id 是 10。当我将 row["id"] 设置为一些小于 10 的值时,我会得到另一个错误 "the id column doesn't allow duplicated value"。这是否意味着我需要在每次将新行插入 table 之前获取最大 ID?

使用什么值并不重要,但不能重复。在这种情况下,我使用负值。您可以使用此逻辑:

DataTable tblAdded = dataSet.Tables[0].GetChanges(DataRowState.Added) ?? new DataTable();
row["id"] = -1 * (tblAdded.Rows.Count + 1);

在这条路上你

  • 始终获得唯一的伪ID(真实值将由数据库插入)
  • 可以看到内存中只添加了哪些行
  • 如果某处重要(f.e。在调试期间)保持插入顺序