Кнопка удаления слишком медленная, в чем проблема - PullRequest
0 голосов
/ 09 января 2019

Я использую этот код для удаления записей, выбранных checkbox в datagridview, но выполнение команды

занимает слишком много времени
private void delete_Click(object sender, EventArgs e)
    {
        foreach(DataGridViewRow item in advancedDataGridView1.Rows)
        {
            if(bool.Parse(item.Cells[0].Value.ToString()))
            {

                conn.Open();
                SqlCommand cmd = new SqlCommand("delete from tabl where id = '" + item.Cells[1].Value.ToString() + "'", conn);
                cmd.ExecuteNonQuery();
                conn.Close();
            }
        }
        MessageBox.Show("Successfully Deleted....");
    }

и я использую этот код для флажка

private void Chkselectall_CheckedChanged(object sender, EventArgs e)
    {
        for(int n = 0; n< advancedDataGridView1.Rows.Count;n++)
        {
            advancedDataGridView1.Rows[n].Cells[0].Value = chkselectall.Checked;
        }
    }

Что мне делать, чтобы решить эту проблему?

Ответы [ 4 ]

0 голосов
/ 13 января 2019

спасибо за вашу помощь я нашел то, что мне нужно, и я надеюсь, что это поможет кому-то еще что-то подобное

String sql;
int parameterCounter;
SqlParameter parameter;

private void delete_Click(object sender, EventArgs e)
{
    sql = "delete from tabl where id in (";
    parameterCounter = 0;

    using (SqlConnection cn = new SqlConnection("....")) {
    using (SqlCommand cmd = new SqlCommand(sql, cn)) {
    foreach (DataGridViewRow item in advancedDataGridView1.Rows) {
     if (bool.Parse(item.Cells[0].Value.ToString())) {
        parameterCounter++;
        parameter = new SqlParameter();
        parameter.ParameterName = "@par" + parameterCounter.ToString();
        parameter.DbType = System.Data.DbType.Int32;
        parameter.Value = item.Cells[1].Value;
        cmd.Parameters.Add(parameter);
        sql = sql + $"{parameter.ParameterName},";
        // collecting all ids
     }
  }
  sql = sql.TrimEnd(',');
  sql = sql + ")";

  cmd.CommandText = sql;
  cmd.Connection = cn;
  cn.Open();
  cmd.ExecuteNonQuery();
    MessageBox.Show("Successfully Deleted....");
}
0 голосов
/ 09 января 2019

Вы должны вывести операции sql из цикла foreach. Создайте строку sql в цикле и выполните ее вне цикла.

private void delete_Click(object sender, EventArgs e)
    {
        StringBuilder sb = new StringBuilder();
        foreach(DataGridViewRow item in advancedDataGridView1.Rows)
        {
            if(bool.Parse(item.Cells[0].Value.ToString()))
            {
                sb.AppendFormat("delete from tabl where id='{0}';{1}", item.Cells[1].Value, Environment.NewLine);

            }
        }
                conn.Open();
                SqlCommand cmd = new SqlCommand(sb.ToString(), conn);
                cmd.ExecuteNonQuery();
                conn.Close();
        MessageBox.Show("Successfully Deleted....");
    }

Теоретически, передача параметров sql напрямую довольно опасна из-за внедрения sql. Вы должны разобраться с этим самостоятельно

0 голосов
/ 09 января 2019

Мало что вы делаете неправильно.

  • Вы используете встроенные запросы, у нас уже есть много потоков (в SO), которые обсуждают эту проблему, поскольку это открывает широкие возможности для SQLInjection.
  • Причиной, которая замедляет производительность выполнения, является способ обработки. т.е. вы перебираете каждую строку и для каждого соответствующего элемента вы открываете соединение и выполняете запрос на удаление.

Я предпочитаю использовать следующие шаги:

  • Итерация по строкам и сбор элементов для удаления в зависимости от условия.
  • построить праметризованный запрос, который принимает параметр типа string.
  • Назначьте собранные идентификаторы в качестве значения параметра.
  • Выполнить запрос.

Пожалуйста, найдите образец кода ниже:

private void delete_Click(object sender, EventArgs e)
{
    List<string> selectedIds = new List<string>();
    foreach (DataGridViewRow item in advancedDataGridView1.Rows)
    {
        if (bool.Parse(item.Cells[0].Value.ToString()))
        {
            selectedIds.Add("'" + item.Cells[1].Value.ToString() + "'");
            // collecting all ids
        }
    }
    String sql = "delete from tabl where id in(@idsToDelete)";
    using (SqlConnection cn = new SqlConnection("Your connection string here")) 
    {
        cn.Open();
        using (SqlCommand cmd = new SqlCommand(sql, cn)) 
        {
            cmd.Parameters.Add("@idsToDelete", SqlDbType.VarChar).Value = string.Join(",", selectedIds);
            cmd.ExecuteNonQuery();
        }
    }      
}
0 голосов
/ 09 января 2019

Ну, вы выполняете кучу команд в последовательности. Для каждого вы открываете новое соединение, закрываете его, и как бы быстро оно ни было, всегда возникают накладные расходы. Вам лучше получить список идентификаторов, которые необходимо удалить, и измените команду на

delete from tabl where id in (…)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...