Member 11856456 Ответов: 3

Функция многорядного удаления


Я могу удалять по одной строке за раз, используя значение ячейки, но я пытался настроить тот же код для mutlirow delete и постоянно получаю ошибку: невозможно использовать объект типа 'System.Int32' для типа 'System.collections.IEnumerable".

Вот код:

Private Sub Datagridview_multiselct_delete() Handles DataGridView1.AllowUserToDeleteRowsChanged

       Try
           For Each dgvr In DataGridView1.SelectedCells.Item(0).Value

               Dim sqlcon As New SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=c:\users\jj\documents\visual studio 2015\Projects\WindowsApplication3\WindowsApplication3\Database1.mdf;Integrated Security=True")
               Dim sqladapt = New SqlDataAdapter("Select * from " + "[" + TreeView1.SelectedNode.Text.ToString, sqlcon)

               sqlcon.Open()
               Dim cmd As SqlClient.SqlCommand
               Dim sql As String = "Delete from " + "[" + TreeView1.SelectedNode.Text.ToString + "]" + " where Id= " + dgvr
               cmd = New SqlClient.SqlCommand(sql, sqlcon)

               cmd.Parameters.AddWithValue("@id", dgvr)

               cmd.ExecuteNonQuery()
               sqlcon.Close()
           Next
           MessageBox.Show("Record deleted")
       Catch ex As Exception
           MsgBox(ex.Message)

       End Try

       Refresh_database()

   End Sub


Что я уже пробовал:

Я попробовал изменить выбранную ячейку на выбранную строку и попытаться построить результаты. Когда я пытаюсь использовать значения в выбранных строках в качестве строки, я постоянно получаю странные сообщения, такие как недопустимое имя столбца T или недопустимое имя столбца S.
вот некоторые из других методов, которые я пробовал:

For Each dgvr In DataGridView1.SelectedRows.Item(0).DataGridView.MultiSelect.ToString
For Each dgvr In DataGridView1.SelectedRows.Item(0).DataBoundItem.ToString
For Each dgvr In DataGridView1.SelectedRows.Item(0).DataGridView.SelectedRows.ToString
For Each dgvr In DataGridView1.SelectedRows.Item(0).DataGridView.Rows.Item(0).Selected.ToString


просто чтобы назвать несколько

3 Ответов

Рейтинг:
20

Michael_Davies

Сообщение об ошибке говорит вам о проблеме, вы пытаетесь перечислить то, что не может быть перечислено.

Перечислите строки в gridview и получите доступ к каждому идентификатору в строке.

Для каждого dgvr как DataGridViewRow в DataGridView1. SelectedRows
... Где id= " +dgvr.Клеток(0).Значение.Метод toString

Затем вы пытаетесь добавить параметр в строку SQL, которая не содержит держателя места параметра, вы фактически объединили параметр в строку, если вы сделаете это таким образом (не рекомендуется), вам это понадобится .Чтобы построить целое число.


Member 11856456

Я просто попробовал сделать это таким образом, и я получил новую ошибку: Public member 'Item' on type 'DataGridViewRow' not found

Michael_Davies

Обновил решение.

Member 11856456

ваше решение было близко, после того, как я повозился с ним, это было то, что я придумал

Для каждого dgvr как DataGridViewRow в DataGridView1. SelectedRows
оператор SQL работал нормально, как только эта часть была настроена, спасибо вам и Мистеру Ричарду за вашу помощь.

Michael_Davies

Вы также открываете и закрываете базу данных в цикле for, теряете время, открываете до for и закрываете после следующего.

Также смотрите решение Мики Венделиуса для одной команды выстрела, чтобы удалить все выбранные за один раз, более эффективно и экономит время.

Рейтинг:
2

Wendelius

Несмотря на то, что вы отметили это как решенное, я бы рекомендовал немного другой подход.

В настоящее время оператор delete выполняется отдельно для каждой строки. Если сетка содержит 100 строк для удаления, вы выполняете 100 отдельных инструкций SQL. Это приводит к большому количеству поездок туда и обратно в базу данных и требует много времени и ресурсов.

Вместо этого почему бы не собрать все ключи внутри цикла for each, а затем удалить все строки с помощью одного оператора using IN сравнение.

Другое дело, что вы открываете и закрываете соединение внутри петли. Это вызывает две вещи:
- использование ресурсов
- отсутствие транзакции между удалениями строк

Вы должны открыть соединение один раз, удалить строки, проверить, что все прошло гладко, а затем закрыть соединение

В-третьих,вы не используете блоки using. Они должны использоваться для того, чтобы правильно распоряжаться ресурсами.

Что касается предложения кода, то псевдокод будет выглядеть следующим образом

for each grid row
   store the id value in a list of strings

using connection
   using command
      sql = "DELETE FROM TableName WHERE ID IN (" & String.Join(", ", stringlist.ToArray)  & ")
      try
         open connection
         execute statement
         close connection
      catch
         handle errors

Пример инструкции delete будет выглядеть следующим образом
DELETE FROM TableName WHERE ID IN (1, 5, 99, 12, 55)


Для получения дополнительной информации об использовании блоков using, транзакций и т. д. Правильное выполнение операций с базой данных[^]


Рейтинг:
1

Richard MacCutchan

For Each dgvr In DataGridView1.SelectedCells.Item(0).Value

Вы не можете выполнить For Each предложение об одном значении. Вы должны сделать это на каком-то типе объекта коллекции. И в приведенном выше случае я бы ожидал, что это будут строки, прикрепленные к SelectedCells.


Member 11856456

Я попытался переключить код на этот:
Для каждого dgvr как DataRowCollection в DataGridView1. SelectedCells.Пункт (0). Значение

но в моем строковом коде SQL я должен изменить его на dgvr. tostring, но я все еще получаю ту же ошибку, что и раньше.

Richard MacCutchan

Да, потому что вы все еще делаете это неправильно. Пожалуйста, прочтите мой ответ выше еще раз и поймите, что вы не можете использовать For Each предложение об одном значении. Если вы действительно не понимаете эту основную концепцию, то вернитесь к своим учебным пособиям и прочтите раздел, посвященный этому пункту.