C # ОБНОВЛЯЕТСЯ непосредственно после ВСТАВКИ, но получает ДОПОЛНИТЕЛЬНУЮ ВСТАВКУ

#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 запускает команду и возвращает значение первого столбца первой строки первого результирующего набора.