当使用ExecuteScalar时,它写入2个记录而不是一个

时间:2014-07-11 04:36:23

标签: c# sql executescalar scope-identity

我需要知道哪些订单号已写入数据库。为此,我使用SQL表达式 EXECUTESCALAR

我调试了程序并监视了数据库。当我执行第二个命令时,记录被写入数据库一次,它第二次写入相同的记录。你能帮我解决一下我需要改变的事情,所以它不会写2条记录而我的订单编号又回来了吗?

这是我的代码:

public static int CreateDocumentNumber(string userId, string todaysDate, decimal docprice, decimal docpaid, int packageId, int orderstatus)
{
    int orderId = 0;   //return value order Id

    //create order 
    string connectionString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    string insertSql = "INSERT INTO [dbo].[LD_Orders](TD_OrdUserID, TD_OrdDate, TD_OrdCost, TD_OrdPaid, TD_OrdPackage, TD_OrdStatus)" +
        " VALUES (@UserId, @Date, @Cost, @Paid, @Package, @Status);SELECT SCOPE_IDENTITY()";

    using (SqlConnection myConnection = new SqlConnection(connectionString))
    {
        myConnection.Open();
        SqlCommand myCommand = new SqlCommand(insertSql, myConnection);
        myCommand.Parameters.Add("@UserId", SqlDbType.VarChar).Value = userId;
        myCommand.Parameters.Add("@Date", SqlDbType.Date).Value = todaysDate;
        myCommand.Parameters.Add("@Cost", SqlDbType.Decimal).Value = docprice;
        myCommand.Parameters.Add("@Paid", SqlDbType.Decimal).Value = docpaid;
        myCommand.Parameters.Add("@Package", SqlDbType.Int).Value = packageId;
        myCommand.Parameters.Add("@Status", SqlDbType.Int).Value = orderstatus;
        myCommand.ExecuteNonQuery();  <---- FIRST RECORD WRITTEN

        // time to collect the last order id
        orderId = Convert.ToInt32(myCommand.ExecuteScalar());   <---- SECOND RECORD WRITTEN

        myConnection.Close();
    }
    return orderId;
}

1 个答案:

答案 0 :(得分:2)

如果删除行myCommand.ExecuteNonQuery();

,您的代码应该有效

ExecuteNonQuery()ExecuteScalar()都将命令发送到SQL Server,唯一的区别是它们如何处理结果。基本上,您正在执行两个您不需要的INSERT语句。

另一方面,现在做硬核ADO.NET编码很少有道理。如果您使用某些ORM,例如Entity Framework或我个人最喜欢的Dapper.NET,您通常可以节省大量时间。

以下是使用Dapper重写整个函数的方法:

public static int CreateDocumentNumber(string userId, string todaysDate, decimal docprice, decimal docpaid, int packageId, int orderstatus)
{
    //create order 
    string connectionString = ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
    string insertSql = "INSERT INTO [dbo].[LD_Orders](TD_OrdUserID, TD_OrdDate, TD_OrdCost, TD_OrdPaid, TD_OrdPackage, TD_OrdStatus)" +
        " VALUES (@UserId, @Date, @Cost, @Paid, @Package, @Status);SELECT SCOPE_IDENTITY()";

    using (SqlConnection myConnection = new SqlConnection(connectionString))
    {
        myConnection.Open();
        int orderId = myConnection.Query<int>(
            insertSql,
            new {
                   UserId = userId,
                   Date = todaysDate,
                   Cost = docprice,
                   Paid = docpaid,
                   Package = packageId,
                   Status = orderstatus
                }).Single();
    }
    return orderId;
}