При использовании ExecuteScalar пишет 2 записи вместо одной
Мне нужно знать, какой номер заказа был записан в базу данных. Для этого я использую выражение 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 ответ
Ваш код должен работать, если вы удалите строку myCommand.ExecuteNonQuery();
И то и другое ExecuteNonQuery()
а также ExecuteScalar()
отправьте команду на сервер SQL, единственное отличие состоит в том, как они обрабатывают результат. По сути, вы выполняете два 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;
}