返回标识值时,ExecuteScalar vs ExecuteNonQuery

如果我想返回新插入行的标识列,请尝试确定是否最好使用ExecuteScalarExecuteNonQuery 。 我已经阅读了这个问题并且我理解了那里的差异,但是在查看几周前我写的一些代码时(虽然从这个网站大量借用)我发现在我的插入中我使用的是ExecuteScalar ,如下所示:

 public static int SaveTest(Test newTest) { var conn = DbConnect.Connection(); const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " + " VALUES ( @tester , @premise ) " + "SET @newId = SCOPE_IDENTITY(); "; using (conn) { using (var cmd = new SqlCommand(sqlString, conn)) { cmd.Parameters.AddWithValue("@tester", newTest.tester); cmd.Parameters.AddWithValue("@premise", newTest.premise); cmd.Parameters.Add("@newId", SqlDbType.Int).Direction = ParameterDirection.Output; cmd.CommandType = CommandType.Text; conn.Open(); cmd.ExecuteScalar(); return (int) cmd.Parameters["@newId"].Value; } } } 

这对我需要的东西很好,所以我很想知道

  1. 我是否应该在这里使用ExecuteNonQuery ,因为它更适合进行插入?
  2. 由于我使用输出参数,检索标识值是否相同?
  3. 是否存在与这种或那种相关的性能命中?
  4. 通常有更好的方法来做到这一点吗?

我正在使用Visual Studio 2010,.NET 4.0和SQL Server 2008r2,以防万一。

正如Aaron所建议的那样,存储过程会使其更快,因为它可以节省Sql Server编译SQL批处理的工作。 但是,您仍然可以采用以下两种方法: ExecuteScalarExecuteNonQuery 。 恕我直言,它们之间的性能差异是如此之小,以至于任何一种方法都是“正确的”。

话虽如此,如果你从输出参数中获取标识值,我没有看到使用ExecuteScalar的意义。 在这种情况下, ExecuteScalar返回的值变得无用。

我喜欢的方法,因为它需要更少的代码,使用没有输出参数的ExecuteScalar

 public static int SaveTest(Test newTest) { var conn = DbConnect.Connection(); const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " + " VALUES ( @tester , @premise ) " + "SELECT SCOPE_IDENTITY()"; using (conn) { using (var cmd = new SqlCommand(sqlString, conn)) { cmd.Parameters.AddWithValue("@tester", newTest.tester); cmd.Parameters.AddWithValue("@premise", newTest.premise); cmd.CommandType = CommandType.Text; conn.Open(); return (int) (decimal) cmd.ExecuteScalar(); } } } 

编程愉快!

编辑 :注意我们需要转换两次:从对象到decimal ,然后再转换为int (感谢techturtle注意到这一点)。