我感觉我没有按照我应该的方式使用表适配器。我在这里阅读了几个问题,this MS article在datagridview(DGV)中处理并发错误。
在我的设置中,我一次只能有一个用户访问该表,并且它将位于该人正在工作的本地HD上。我在tabcontrol中的多个选项卡上使用多个DGV。 DGV绑定到Access DB中的表。当用户尝试跨两行或多行在多个单元格上输入值时,它们将在第二行上的第二个单元格后遇到并发错误。处理完并发错误后,再次重新填充更新主键列的DGV,它们就不会有任何错误。
回到DGV中的现有值也不会导致错误,似乎只有在密钥列(用户没有输入但可以排序)Is DBNull
时才会发生。
这是我到目前为止所得到的:
Dim m_DtChemical As New DataTable
Dim ChemicalAdapter As OleDbDataAdapter
Dim m_Bsource As New BindingSource
Sub FillChemicalDataGrid()
ChemicalAdapter = New OleDbDataAdapter("Select * From Chemicals", ConMain)
m_DtChemical.Clear()
ChemicalAdapter.Fill(m_DtChemical)
m_Bsource.DataSource = m_DtChemical
ChemicalDataGridView.DataSource = m_Bsource
End Sub
Sub UpdateChemicalsDatabase()
Try
Dim ObjComander As New OleDbCommandBuilder(ChemicalAdapter)
ChemicalAdapter.Update(m_DtChemical)
Catch ex2 As DBConcurrencyException
OhGodImStuckErrorHandler()
MsgBox("Concurrency Error. Reloading Table.")
FillChemicalDataGrid()
Catch ex As Exception
MsgBox("There was an error updating to the database. " & ex.Message)
WriteToErrorLog(ex.Message, ex.StackTrace, ex.GetHashCode, ex.Source, ex.ToString)
End Try
End Sub
Private Sub ChemicalDataGridView_RowValidated(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DataGridViewCellEventArgs) Handles ChemicalDataGridView.RowValidated 'tried CellLeave, CellEnter, CellValidated...etc
Call UpdateChemicalsDatabase()
End Sub
我试图让合并和更新发生,特别是If IsDBNull(DGV(0, Xrow).Value) = true
在我想要做的事情上,我是否会离开?它似乎只来自ID(主键列)实际上是DBNull的实例。有没有更好的方法来处理这个问题?而不是处理并发错误,我觉得我应该能够首先避免它,如果我能弄清楚如何。
我在VB.net和C#中有类似的项目,两者都有完全相同的问题。我在VB.Net上稍微舒服一点,但我很乐意用以太的方式回答。
编辑:根据评论描述情景:
因此,用户会进入并填写DGV中新行的单元格(例如名称)。如果他们只填写一行,那么所有内容都会正确更新/插入,数据库会为其分配一个ID,并在下次访问时显示备份。如果他们尝试在每个新行中写入多个列,则会引发并发错误。我注意到,当他们添加每个新行时,DGV的ID为DBNull,但是当刷新或填充它时,它将使用DB生成的ID。当DGV在ID列中显示正确的密钥时,它永远不会遇到并发错误。
答案 0 :(得分:1)
处理并发问题的一种方法是确定脏行。
检查某些内容是否脏的一种方法是在查询期间,您应该获取该行的时间戳(例如,该行具有时间戳列,并且在更新期间,此列设置为getdate())
现在,在您的应用程序中进行实际更新之前,您要做的是首先加载您要更新的行的时间戳,如果您对该行的时间戳与DB中的时间戳匹配,那么您知道不要有一个脏行,你可以继续更新。
现在,如果你有一个脏行..你有一些事情要考虑如何处理它...像 - 也许
取决于您的要求。
答案 1 :(得分:1)
问题在于你的" Key列"允许DBNull。您必须拥有MS的主键列才能合并记录并防止您多次拥有相同的记录。
这里发生的事情是您在缓存中多次使用相同的记录,当您更新一条记录时,另一条记录不同步。通过使用单个数据集并将主键应用于每个数据表,可以消除多个复制的数据。当您执行类似DataAdapter.Fill()的操作时,MS将合并数据,而不是盲目地再次添加相同的记录。然后当你保存时,它将更新并重置记录上的标志,以便下次保存时,你不会遇到同意错误。