SqlDataAdapter.Fill(DataGridView.DataSource) duplicates all rows

纵然是瞬间 提交于 2019-12-02 13:20:25

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 ...

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!