2014-01-09 6 views
1

У меня есть таблица SQL, которая выглядит примерно так:DataGridView не обновляется

1 | a | ...

2 | a | ...

3 | b | ...

4 | a | ...

5 | b | материал ...

Я только хочу, чтобы показать:

3 | b | ...

5 | b | материал ...

Поэтому я использую этот код для загрузки DataGridView:

Private Sub GetData() 

    Dim objConn As New SqlConnection(sConnectionString) 
    objConn.Open() 

    ' Create an instance of a DataAdapter. 
    Dim daInstTbl As _ 
     New SqlDataAdapter("SELECT * FROM Table WHERE Column = 'b'", objConn) 

    ' Create an instance of a DataSet, and retrieve data from the Authors table. 
    daInstTbl.FillSchema(dsNewInst, SchemaType.Source) 
    daInstTbl.Fill(dsNewInst) 

    ' Create a new instance of a DataTable 
    MyDataTable = dsNewInst.Tables(0) 

    daInstTbl.Update(dsNewInst) 
End Sub 
Private Sub InitializeDataGridView() 
    Try 
     ' Set up the DataGridView. 
     With Me.DataGridView1 

      ' Set up the data source. 
      .DataSource = MyDataTable 

     End With 

    Catch ex As SqlException 
     MessageBox.Show(ex.ToString, _ 
      "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) 
     System.Threading.Thread.CurrentThread.Abort() 
    End Try 
End Sub 

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

Вот мой код удаления:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click 
    Dim objConn As New SqlConnection(sConnectionString) 
    objConn.Open() 
    Dim daInstDeleteTbl As New SqlDataAdapter("SELECT * FROM Table", objConn) 
    Dim dsDeleteInst As New DataSet 
    Dim MyDeleteTable As DataTable 
    ' Create an instance of a DataSet, and retrieve data from the Authors table. 
    daInstDeleteTbl.FillSchema(dsDeleteInst, SchemaType.Source) 
    daInstDeleteTbl.Fill(dsDeleteInst) 

    ' Create a new instance of a DataTable 
    MyDeleteTable = dsDeleteInst.Tables(0) 

    'Begin Delete Code 

    Dim DeleteID, DeleteIndex As Integer 
    Dim MadeChange As Boolean = False 
    Integer.TryParse(TextBox1.Text, DeleteID) 
    Dim dgvIndexCount As Integer = MyDeleteTable.Rows.Count - 1 
    If MyDeleteTable.Rows(dgvIndexCount).Item(0) > DeleteID Then 
     Dim counter As Integer = -1 
     For Each row As DataRow In MyDeleteTable.Rows 
      counter += 1 
      If row.Item("Column") = DeleteID Then 
       DeleteIndex = counter 
      End If 
     Next 
     MadeChange = True 
    End If 
    drCurrent = MyDeleteTable.Rows.Find(DeleteID) 
    drCurrent.Delete() 
    If MadeChange = True Then 
     Dim i As Integer = 0 
     For i = DeleteIndex + 1 To dgvIndexCount 
      MyDeleteTable.Rows(i).Item(0) = MyDeleteTable.Rows(i).Item(0) - 1 
     Next 
    End If 

    'Send Changes to SQL Server 
    Dim objCommandBuilder As New SqlCommandBuilder(daInstDeleteTbl) 
    daInstDeleteTbl.Update(dsDeleteInst) 

    Dim daInstTbl As _ 
     New SqlDataAdapter("SELECT * FROM Table WHERE Column = 'b'", objConn) 
    Dim objCommandReBuilder As New SqlCommandBuilder(daInstTbl) 
    daInstTbl.Update(dsNewInst) 

End Sub 

Я думаю, что я делаю много дополнительной работы, чтобы сделать это неправильно. Есть идеи? Благодарю.

+1

Существуют ли какие-либо из этих методов, вызываемых в «BackgroundWorker» или в другом «Thread»? –

+0

@ Bjørn-RogerKringsjå - Нет. Все однопоточные прямо сейчас. Единственное, что я не показываю, это события Form1, Add и Update. Form1 просто вызывает GetData() и InitializeDataGridView(). – ZL1Corvette

+0

Хорошо, я посмотрю. –

ответ

0

Мое решение состояло в том, чтобы изменить способ объявления переменных. До того как я имел:

Dim daInstTbl As _ 
    New SqlDataAdapter("SELECT * FROM Table WHERE Column = 'b'", objConn) 

аффекта, что ссылаясь на подпрограмму игнорировали эту линию, так как переменная daInstTbl уже объявлена ​​ранее.Раствор был:

' Delete old instance of a Data____ classes 
    da = Nothing 
    ds = Nothing 
    dt = Nothing 

    If GetAll = False Then 
     da = New SqlDataAdapter(sSelCmd, objConn) 
    Else 
     da = New SqlDataAdapter(sSelAllCmd, objConn) 
    End If 

    ' Create an instance of a DataSet, and retrieve data from the Authors table. 
    ds = New DataSet 
    da.FillSchema(ds, SchemaType.Source) 
    da.Fill(ds) 

Это очистило информацию и позволило мне присвоить новое значение. Мои подпрограммы выполняют двойную функцию, назначая две строки запроса, а затем используя необязательное логическое значение, чтобы определить, какую версию использовать.

Dim sSelCmd As String = "SELECT * FROM Table WHERE Coloumn= 'b'" 
Dim sSelAllCmd As String = "SELECT * FROM Table" 

Private Sub GetData(Optional ByVal GetAll As Boolean = False) 
    Dim objConn As New SqlConnection(sConnectionString) 
    objConn.Open() 

И что приводит к вышеуказанному коду! Спасибо за помощь. Некоторые из ваших концепций заставили мои мысли повернуться в правильном направлении и побудили меня очистить мой код в гораздо более читаемой форме.

1

При вызове SqlDataAdapter.Update() адаптер обновляет значения в базе данных, выполнив соответствующие INSERT, UPDATE или DELETE(from MSDN). Команда SELECT не выполняется. Так что вам нужно сделать это следующим образом:

Insert/Update/Delete:

daInstTbl.Update(dsNewInst) 

Выбрать:

daInstTbl.Fill(dsNewInst) 

Commit:

dsNewInst.AcceptChanges() 

Пример

Private connection As SqlConnection 
Private adapter As SqlDataAdapter 
Private data As DataSet 
Private builder As SqlCommandBuilder 
Private grid As DataGridView 

Private Sub InitData() 
    Me.SqlSelect(firstLoad:=True, fillLoadOption:=LoadOption.OverwriteChanges, acceptChanges:=True) 
    Me.grid.DataSource = Me.data 
    Me.grid.DataMember = "Table" 
End Sub 

Public Sub SaveData() 
    Me.SqlInsertUpdateAndDelete() 
    Me.SqlSelect(fillLoadOption:=LoadOption.OverwriteChanges, acceptChanges:=True) 
End Sub 

Public Sub RefreshData(preserveChanges As Boolean) 
    Me.SqlSelect(fillLoadOption:=If(preserveChanges, LoadOption.PreserveChanges, LoadOption.OverwriteChanges)) 
End Sub 

Private Sub SqlSelect(Optional firstLoad As Boolean = False, Optional ByVal fillLoadOption As LoadOption = LoadOption.PreserveChanges, Optional acceptChanges As Boolean = False) 

    If (firstLoad) Then 
     Me.data = New DataSet() 
     Me.connection = New SqlConnection("con_str") 
     Me.adapter = New SqlDataAdapter("SELECT * FROM Table WHERE Column = 'b'", connection) 
     Me.builder = New SqlCommandBuilder(Me.adapter) 
    End If 

    Me.connection.Open() 

    If (firstLoad) Then 
     Me.adapter.FillSchema(Me.data, SchemaType.Source, "Table") 
    End If 

    Me.adapter.FillLoadOption = fillLoadOption 
    Me.adapter.Fill(Me.data, "Table") 

    If (acceptChanges) Then 
     Me.data.Tables("Table").AcceptChanges() 
    End If 

    Me.connection.Close() 

End Sub 

Private Sub SqlInsertUpdateAndDelete() 

    If (Me.connection.State <> ConnectionState.Open) Then 
     Me.connection.Open() 
    End If 

    Me.adapter.Update(Me.data, "Table") 

    Me.connection.Close() 

End Sub 

PS: (Untested code)

+0

Не работает, так что, полагаю, я поставил это не в том месте? Я едва еду на воду. Если я правильно прочитал эту статью MSDN, то .Update не должен исправлять такие вещи, как изменение «a» на «b», просто введя новое значение в DataGridView. – ZL1Corvette

+1

'.Update 'обновляет вашу базу данных, а не ваш' DataSet'. А поскольку данные заселяются так, как ожидалось после перезагрузки, '.Update' работает. Ваша проблема заключается в том, как вы обрабатываете «Обновление» данных. Я приведу пример, просто дай мне минуту. –

+0

@ ZL1Corvette Я приложил пример. Код - это непроверенный фиктивный код. Просто используйте его как ссылку на то, как работает этот процесс. –

Смежные вопросы