SqlDataAdapter.Fill(DataGridView.DataSource) duplicates all rows

后端 未结 2 753
日久生厌
日久生厌 2021-01-28 13:10

Simple question:

When I call SqlDataAdapter.Fill(DataGridView.DataSource) the second time after initially creating first Data it does not update the contain

相关标签:
2条回答
  • 2021-01-28 14:00

    From MSDN:

    You can use the Fill method multiple times on the same DataTable. If a primary key exists, incoming rows are merged with matching rows that already exist. If no primary key exists, incoming rows are appended to the DataTable.

    So either define a primary key or clear the table first.

    Dim table = CType(DataGridView.DataSource, DataTable)
    table.Clear()
    ' fill  ...
    

    To define primary key(s) manually read this. To let it create automatically if they are defined in the database you need to set the MissingSchemaAction to AddWithKey:

    ' ...
    dataAdapter.MissingSchemaAction =  MissingSchemaAction.AddWithKey
    ' fill ...
    
    0 讨论(0)
  • 2021-01-28 14:05

    The edit code doesnt show the PrimaryKey being defined for the DataTable. This will configure the DataAdapter to perform updates and enabled refreshing the DataTable. The code uses MySQL but the Provider objects all work the same in this regard:

    ' persistant form level vars
    Private daSample As MySqlDataAdapter
    Private dtSample As DataTable
    ...
    

    Elsewhere:

    ' there are caveats with WHERE clauses
    Dim sql = "SELECT Id, Name, Country, Animal FROM SAMPLE WHERE Color = 'onyx'"
    
    ' using the ctor overload, no need for a DbCommand or Connection object
    daSample = New MySqlDataAdapter(sql, MySQLConnStr)
    
    ' initialize the CommandBuilder, get other commands 
    Dim cbSample = New MySqlCommandBuilder(daSample)
    
    daSample.UpdateCommand = cbSample.GetUpdateCommand
    daSample.InsertCommand = cbSample.GetInsertCommand
    daSample.DeleteCommand = cbSample.GetDeleteCommand
    
    dtSample = New DataTable()
    daSample.FillSchema(dtSample, SchemaType.Source)
    dtSample.PrimaryKey = New DataColumn() {dtSample.Columns("id")}
    
    daSample.Fill(dtSample)
    
    dgv1.DataSource = dtSample
    

    To pick up changes made to the db from other client apps:

    daSample.Fill(dtSample)
    

    Initial display:

    After I change a row to "onyx" from a UI browser and Update the changed row shows up:

    WHERE clauses can be a bit of an issue. Since it restricts the subset of data pulled back, Update is only going to compare rows in the new result set. So, if I change an onlyx row to "blue" it wont be removed.

    One solution is to use .DefaultView.RowFilter on the table, but that can slow things down since it requires returning all rows to the client to be filtered there. Its not perfect.

    0 讨论(0)
提交回复
热议问题