C# 从MS SQL Server获取自动编号主键

C# 从MS SQL Server获取自动编号主键,c#,sql-server,autonumber,C#,Sql Server,Autonumber,我目前在C#中工作,需要在一个表中插入一条新记录,获取新的主键值,然后在插入多条记录时将其用作外键引用。数据库是MS SQL Server 2003。感谢您的帮助 最好的方法是在TSQL中使用SCOPE_IDENTITY()函数。这应作为插入的一部分执行,即 SqlCommand cmd = new SqlCommand(@" INSERT INTO T (Name) VALUES(@Name) SELECT SCOPE_IDENTITY() As TheId", conn);

我目前在C#中工作,需要在一个表中插入一条新记录,获取新的主键值,然后在插入多条记录时将其用作外键引用。数据库是MS SQL Server 2003。感谢您的帮助

最好的方法是在TSQL中使用SCOPE_IDENTITY()函数。这应作为插入的一部分执行,即

SqlCommand cmd = new SqlCommand(@"
    INSERT INTO T (Name) VALUES(@Name)
    SELECT SCOPE_IDENTITY() As TheId", conn);
cmd.AddParameter("@Name", SqlDbType.VarChar, 50).Value = "Test";
int tId = (int)cmd.ExecuteScalar();
或者,您可以将SCOPE_IDENTITY()指定给要在后续语句中使用的变量。e、 g

DECLARE @T1 int

INSERT INTO T (Name) VALUES('Test')

SELECT @T1 = SCOPE_IDENTITY() 

INSERT INTO T2 (Name, TId) VALUES('Test', @T1)

获取插入行的标识的方法是使用
SCOPE\u identity()
函数。如果您使用的是存储过程,那么将行标识作为输出参数返回,如下所示

CREATE PROCEDURE dbo.MyProcedure
(
    @RowId INT = NULL OUTPUT
)
AS

INSERT INTO MyTable
(
    Column1
    ,Column2
    ,...
)
VALUES
(
    @Param1
    ,@Param2
    ,...
);

SET @RowId = SCOPE_IDENTITY();
然后可以将此值用于任何后续插入(或者,如果可以将所有数据传递到存储过程中,则可以在过程体的其余部分中使用它)

如果要动态传入SQL,则使用大致相同的技术,但使用带有语句分隔符的单个字符串(在SQL中也是
),例如:

然后,如果使用
ExecuteScalar
执行此操作,您将能够将标识作为标量结果返回,并将其转换为正确的类型。或者,您可以一次完成整个批次,例如

var sql = "DECLARE @RowId INT;" + 
          "INSERT INTO MyTable (Column1, Column2, ...) VALUES (@P1, @P2, ...);" +
          "SET @RowId = SCOPE_IDENTITY();" +
          "INSERT INTO MyOtherTable (Column1, ...) VALUES (@P3, @P4, ...);";

这可能不是正确的语法,您可能需要使用
SET NOCOUNT-ON
一开始(我的脑子已经生锈了,因为我很少使用动态SQL),但这应该会让你走上正轨。

如果你只是在使用SQL,那么请检查Duncan的答案。如果您使用LINQ,那么您可以创建实体,将其保存到DB,ID参数将自动填充

给定一个用户实体和一个用户表,它可能如下所示:

using(var db = new DataContext()) {
    var user = new User { Name = "Jhon" };
    db.Users.InsertOnSubmit(user);
    db.SubmitChanges();
    /* At this point the user.ID field will have the primary key from the database */
}

所有这些都是一个字符串,还是作为单独的字符串传入?你的解决方案不清楚这一点。记住,我是通过C#进行SQL查询的。在这两种情况下,都可以传递一个字符串。对于第一个方法,可以使用SqlCommand ExecuteScaler()获取刚刚插入的行的标识。您还需要使用command.AddParameter将硬编码的“Test”绑定到@Name参数,以避免sql注入。与返回数据集相比,我更喜欢这种方法(使用OUT参数)。特别是对于自动生成的代码。您可以通过调用.ExecuteScalar()跳过数据集。我更喜欢输出参数,因为我认为它们比标量结果集更具有自文档性,但任何一种方法都可以。您是使用像LINQ这样的框架还是使用SQL字符串查询?(在我的回答中,我假设是LINQ)这是LINQ到sql、LINQ到实体或dbcontext。以防有人意识到。。。
using(var db = new DataContext()) {
    var user = new User { Name = "Jhon" };
    db.Users.InsertOnSubmit(user);
    db.SubmitChanges();
    /* At this point the user.ID field will have the primary key from the database */
}