c#在Transaction中检索插入的ID

时间:2018-03-07 16:25:12

标签: c# asp.net sql-server transactions rollback

我想在事务中拥有一堆插件,以便在出现任何错误时可以回滚。现在我的问题是,对于某些插入,我需要前一个插入的ID。但是,执行var id = (int)command.ExecuteScalar();会抛出异常("对象引用未设置为对象的实例")。如果我在不尝试分配结果的情况下运行command.ExecuteScalar(),则代码可以正常工作。在提交交易之前是否可以获得ID?如果不是,我的替代方案是什么?

我的代码:

using (SqlConnection connection = new SqlConnection("ConnectionHere")
{
            connection.Open();

            SqlCommand command = connection.CreateCommand();
            SqlTransaction transaction;

            // Start a local transaction.
            transaction = connection.BeginTransaction();
            command.Connection = connection;
            command.Transaction = transaction;

            try
            {                    
                string insertStudent = "INSERT INTO Students (FirstName, MiddleName, LastName)" +
                " VALUES (@firstName, @middleName, @lastName)";

                command.CommandText = insertStudent;
                command.Parameters.AddWithValue("@firstName", application.FirstName);
                command.Parameters.AddWithValue("@middleName", application.MiddleName);
                command.Parameters.AddWithValue("@lastName", application.LastName);

                var id = (int) command.ExecuteScalar();//EXCEPTION THROWN HERE

                // Attempt to commit the transaction.
                transaction.Commit();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Commit Exception Type: {0}", ex.GetType());
                Console.WriteLine("  Message: {0}", ex.Message);

                // Attempt to roll back the transaction.        
                transaction.Rollback();
            }
}

3 个答案:

答案 0 :(得分:1)

我假设Students表中的一列被设置为标识列,并且您使用的是SQL Server 2008 +。

在这种情况下,您需要更改SQL语句以返回插入的标识值,如下所示:

  string insertStudent = "INSERT INTO Students (FirstName, MiddleName, LastName)" +
            " VALUES (@firstName, @middleName, @lastName);" +
            " SELECT SCOPE_IDENTITY();";

有关SCOPE_IDENTITY的更多信息,请访问:https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql

答案 1 :(得分:0)

使用此SQL语法获取插入的ID:

INSERT INTO Students (FirstName, MiddleName, LastName) OUTPUT Inserted.ID .... 

然后

int id = command.ExecuteScalar();

答案 2 :(得分:0)

只需更改代码

即可
  var id = (int) command.ExecuteScalar();

为:

int id = Convert.ToInt32(cmd.ExecuteScalar());

这将确保即使ExecuteScalar返回null,由于未在存储过程中选择任何内容,countDis的值也为0.因为Convert.ToInt32(null)= 0。