vb.netvisual-studioupdatestableadaptersavechanges

TableAdapter data has changed but property "has Changes" stays at "false" so udate does nothing


It's mostly in the title... I'm using VB (obviously, see below), but I'm a total beginner with visual studio.

Here is the test code I'm using (it is a simple test button I designed to test the problem I have in the code elsewhere):

    Private Sub Test_Click(sender As Object, e As EventArgs) Handles Test.Click
        Dim FDBdataset As New FDBDataSet()
        Dim FDBTableAdapter As New FDBDataSetTableAdapters.T_PicturesTableAdapter
        For Each row As DataRow In FDBTableAdapter.GetData()
            row.BeginEdit()
            If row("id").ToString = 58672.ToString Then
                row.BeginEdit()
                Console.Write("Previous Value = " & row("ImgFileName").ToString)
                row("ImgFileName") = "Tagada"
                row.EndEdit()
                Console.WriteLine(", Current Row Value = " & row("ImgFileName").ToString & " - HasChanges : " & FDBdataset.HasChanges())
            End If
        Next
        FDBTableAdapter.Update(FDBdataset)

The output in the console is:

Previous Value = Aphidecta_obliterata_58672, Current Row Value = Tagada - HasChanges : False

I don't understand what is wrong and how to correct it... I would be very grateful for some help here !

TableAdapter seems set up correctly, and I can read from it, parse rows; display field values, etc... Update method reports as being correctly set up by the datasource designer. Code runs without errors but does not affect the DB content.


Solution

  • Why would you think that FDBdataset has any changes in it? Where are you making any changes to it? You have this:

    For Each row As DataRow In FDBTableAdapter.GetData()
    

    and GetData returns a new DataTable, so you're making change to that DataTable completely independent of FDBdataset. Use one or the other but not both.

    Based on the code you have there, you don't need the DataSet. You can just use the DataTable returnd by GetData:

    Dim adapter As New FDBDataSetTableAdapters.T_PicturesTableAdapter
    Dim table = FDBTableAdapter.GetData()
    
    For Each row In table
        If row.id = 58672 Then
            row.ImgFileName = "Tagada"
        End If
    Next
    
    adapter.Update(table)
    

    Notice that I tidied up your code a lot too. If you're going to use a typed DataSet then use it.

    If you actually do need a DataSet for some reason then make the changes to it, not an unrelated DataTable:

    Dim data As New FDBDataSet
    Dim adapter As New FDBDataSetTableAdapters.T_PicturesTableAdapter
    
    adapter.Fill(data)
    
    For Each row In data.T_Pictures
        If row.id = 58672 Then
            row.ImgFileName = "Tagada"
        End If
    Next
    
    adapter.Update(data)
    

    That second code snippet may need some adjustments but I think it should work.

    So, the moral of the story is that the Fill method populates an existing DataTable, which can be part of a DataSet but doesn't have to be, while the GetData method creates a new DataTable, populates it and returns it. That new DataTable is not part of any DataSet.