【问题标题】:DataGridView with DataTable/BindingSource Not Showing New Autonumber ID具有 DataTable/BindingSource 的 DataGridView 未显示新的自动编号 ID
【发布时间】:2014-02-09 23:11:36
【问题描述】:

我有一个表单,其 DataGridView 绑定到一个 BindingSource 对象,该对象连接到一个使用 Autonumber 作为 ID 字段的 Access 数据库。

当记录被编辑、删除或创建时,我运行 DataAdapter 的更新方法,该方法效果很好。但新记录不显示其 ID,并且尝试删除新记录会导致 DBConCurrencyException。

我有什么方法可以告诉 BindingSource、Databable 或 Dataset 刷新/重新加载记录吗?显示新记录的自动编号 ID 的最佳方式是什么?

(警告,我知道这不是写得很好,抽象得很好的代码。)

Private conString As String = "Provider=Microsoft.ACE.OLEDB.12.0; " +
                            "Data Source=C:\data.accdb"
Private conn As OleDbConnection
Private WithEvents da As OleDbDataAdapter
Private ds As DataSet
Private builder As OleDbCommandBuilder
Private WithEvents bs As BindingSource

Private Sub AccessDataGridView_Load(sender As Object, e As EventArgs) Handles Me.Load
    dgv1.AutoGenerateColumns = True
    Call GetData("SELECT * FROM lots")
    dgv1.DataSource = bs
    dgv1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)
End Sub

Private Function GetData(sSQL As String)
    If conn Is Nothing Then
        conn = New OleDbConnection
        conn.ConnectionString = conString
        conn.Open()
    End If
    da = New OleDbDataAdapter(sSQL, conn)
    builder = New OleDbCommandBuilder(da)
    ds = New DataSet
    da.Fill(ds)
    bs = New BindingSource
    bs.DataSource = ds.Tables(0)
End Function

Private Sub bs_CurrentItemChanged(sender As Object, e As EventArgs) Handles bs.CurrentItemChanged
    If ds.HasChanges() = True Then
        da.Update(CType(bs.DataSource, DataTable))
    End If
End Sub

Private Sub bs_ListChanged(sender As Object, e As System.ComponentModel.ListChangedEventArgs) Handles bs.ListChanged
    If ds.HasChanges() = True Then
        da.Update(CType(bs.DataSource, DataTable))
    End If
End Sub

Private Sub da_RowUpdated(sender As Object, e As OleDbRowUpdatedEventArgs) Handles da.RowUpdated
    If e.Status = UpdateStatus.Continue _
          AndAlso e.StatementType = StatementType.Insert Then
        Dim cmdGetIdentity As OleDbCommand
        cmdGetIdentity = New OleDbCommand()
        cmdGetIdentity.CommandText = "SELECT @@IDENTITY"
        cmdGetIdentity.Connection = conn
        e.Row("lotid") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString())
        e.Row.AcceptChanges()
        'This appears to work with no problem, but the DataGridView
        'still doesn't show the new ID
        'EDIT
        dgv1.Refresh() 'This fixed the problem mentioned directly above
    End If
End Sub

【问题讨论】:

    标签: vb.net datagridview datatable ado.net bindingsource


    【解决方案1】:

    使用 SqlClient 时自动生成的 ID 被传播回 DataTable 的方式是在 InsertCommand 的 CommandText 中包含一个 SELECT 语句。 Jet 和 ACE OLE DB 提供程序不支持每个命令的多个语句,因此这不是一个选项。我已经在另一个站点上专门为 Access 编写了一些示例代码,但目前它已经关闭,所以我不能给你链接。这是另一个例子:

    http://support.microsoft.com/kb/816112/en-gb

    该代码是 C#,但原理完全相同:处理数据适配器的 RowUpdated 事件,从数据库中获取 ID 并更新 DataRow。

    【讨论】:

    • 我用了那个例子。请参阅我在上面粘贴的附加代码。就像我的 DataAdapter 和我的 BindingSource 对象之间存在某种脱节。更新永远不会弥补 DataGridView。
    • 那个其他网站现在已经重新上线,所以这是我想首先提供的链接:vbforums.com/…
    • 好的,我认为我不需要 .NET 来插入唯一 ID,就像在该示例中一样。起作用的是我在检索最后一个 ID 的代码之后添加了 DataGridView.Refresh()。
    猜你喜欢
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 2019-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 1970-01-01
    相关资源
    最近更新 更多