#c# #sql-server
#c# #sql-server
Вопрос:
У меня есть следующий код:
private void btnAddMatter_Click(object sender, EventArgs e)
{
MatterCode = "";
EntityID = 0;
FeeEarnerID = 0;
OpenedByUserID = 0;
CompanyContactDetailsID = 0;
Description = "";
OurReference = "";
TheirReference = "";
DateOpened = DateTime.Now;
MatterTypeID = 0;
DepartmentID = 0;
ResponsibleUserID = 0;
TrustBankAccountID = 0;
BusinessBankAccountID = 0;
string connectionString = "Data Source=***\SQLEXPRESS;Initial Catalog=STUPELG;Persist Security Info=True;User ID=***;Password=***";
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Matter ( MatterCode, EntityID, FeeEarnerID, OpenedByUserID, CompanyContactDetailsID, Description,"
" OurReference, TheirReference, DateOpened, MatterTypeID, DepartmentID, ResponsibleUserID, TrustBankAccountID, BusinessBankAccountID)"
" VALUES ( @MatterCode, @EntityID, @FeeEarnerID, @OpenedByUserID, @CompanyContactDetailsID, @Description,"
" @OurReference, @TheirReference, @DateOpened, @MatterTypeID, @DepartmentID, @ResponsibleUserID, @TrustBankAccountID, @BusinessBankAccountID);"
" SELECT SCOPE_IDENTITY();");
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("@MatterID", MatterID);
cmd.Parameters.AddWithValue("@MatterCode", MatterCode);
cmd.Parameters.AddWithValue("@EntityID", EntityID);
cmd.Parameters.AddWithValue("@FeeEarnerID", FeeEarnerID);
cmd.Parameters.AddWithValue("@OpenedByUserID", OpenedByUserID);
cmd.Parameters.AddWithValue("@CompanyContactDetailsID", CompanyContactDetailsID);
cmd.Parameters.AddWithValue("@Description", Description);
cmd.Parameters.AddWithValue("@OurReference", OurReference);
cmd.Parameters.AddWithValue("@TheirReference", TheirReference);
cmd.Parameters.AddWithValue("@MatterTypeID", MatterTypeID);
cmd.Parameters.AddWithValue("@DepartmentID", DepartmentID);
cmd.Parameters.AddWithValue("@ResponsibleUserID", ResponsibleUserID);
cmd.Parameters.AddWithValue("@TrustBankAccountID", TrustBankAccountID);
cmd.Parameters.AddWithValue("@BusinessBankAccountID", BusinessBankAccountID);
cmd.Parameters.AddWithValue("@DateOpened", DateOpened);
connection.Open();
cmd.ExecuteNonQuery();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet NewMatterID = new DataSet();
adapter.Fill(NewMatterID);
MatterCode = Convert.ToString(NewMatterID.Tables[0].Rows[0][0]);
}
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("UPDATE Matter SET MatterCode = @MatterCode WHERE MatterID = " MatterCode);
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("@MatterCode", MatterCode);
connection.Open();
cmd.ExecuteNonQuery();
}
MessageBox.Show("Matter " MatterCode " successfully created");
}
После вставки строки новый MatterID (первичный ключ, который генерируется автоматически) должен быть скопирован в поле MatterCode. В настоящее время это работает, ЗА ИСКЛЮЧЕНИЕМ того, что при нажатии кнопки создается дополнительная строка:
Как мне это исправить???
Комментарии:
1. cmd.ExecuteNonQuery() и адаптер. Fill(NewMatterID) дважды выполнит запрос insert
2. Просто чтобы вы знали: AddWithValue — это зло , AddWithValue — это зло! и можем ли мы уже прекратить использовать AddWithValue() ? .
3. Дополнительные моменты: 1. Нет необходимости в адаптере, поскольку вы возвращаете только одно значение, используйте
(int) (decimal) cmd.ExecuteScalar()
вместо этого. 2. Вы объединяете значение во втором запросе, вместо этого используйте параметр 3. Вам все равно не нужно запускать два запроса, вы можете выполнить все это в одном пакетеINSERT
, за которым следуетUPDATE ... WHEREMatterIid = SCOPE_IDENTITY()
. Не забывайте, что вы можете вызвать толькоSCOPE_IDENITTY
один раз, если вам нужно повторно использовать, а затем сохранить в переменной
Ответ №1:
Ну, это потому, что ваш код выполняет INSERT
запрос дважды……
connection.Open();
cmd.ExecuteNonQuery(); // first execution
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet NewMatterID = new DataSet();
adapter.Fill(NewMatterID); // second execution
Я не совсем уверен, что вы хотели с этим SqlDataAdapter
сделать, но он использует то же SqlCommand
самое, что и раньше, с INSERT
инструкцией, которая выполняется во второй раз……
Ответ №2:
Вы можете заменить это:
cmd.ExecuteNonQuery();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet NewMatterID = new DataSet();
adapter.Fill(NewMatterID);
MatterCode = Convert.ToString(NewMatterID.Tables[0].Rows[0][0]);
с
MatterCode = cmd.ExecuteScalar().ToString();
as ExecuteScalar
запускает команду и возвращает значение первого столбца первой строки первого результирующего набора.