在数据访问层,我们一般使用DataAdapter来获取或更新数据库数据。很经常地,我们使用 CommandBuilder为DataAdapter自动创建InsertCommand、UpdateCommand、DeleteComand。这 种方式确实很方便,仅需很少的代码就能完成数据库更新。但使用这种方式有时会产生DBConCurrencyException 并 发冲突异常。
DataAdapter 检查每次执行的插入、更新或删除操作所影响的行数,如果行数等于零,则引发DBConCurrencyException 异 常。而实际产生此异常的原因是:使用CommandBuilder为DataAdapter自动创建的更新Command,它们的Where子句包含了相 应表结构中的所有字段的比较,就是说,在更新一条记录之前,先通过比较所有的字段而不是仅通过主键的比较来查询这条记录,然后再更新。自从上次获取数据记 录之后,如果该数据记录被更新了,那么DataAdapter就会因为找不到该条记录而产生此异常。
一个较简单的解决方法是,设置CommandBuilder的相关属性:ConflictOption和SetAllValues。
'
'' <summary>
'
'' 使用SqlCommandBuilder的数据库更新
'
'' </summary>
'
'' <param name="sqlSelect">用于查询数据的SQL语句,用于设置DataAdapter的SelectCommand< /param>
'
'' <param name="dtChanged">包含要更新的数据的DataTable</param>
'
'' <returns>结果更新的行数</returns>
'
'' <remarks></remarks>
Public
Function UpdateDB( ByVal sqlSelect As String , ByVal dtChanged As System.Data.DataTable) As Integer
Dim daUpdate As SqlDataAdapter = New SqlDataAdapter(sqlSelect, m_dbConnection) ' m_dbConnection: 数据库连接
Dim cmdBuild As SqlCommandBuilder = New SqlCommandBuilder()
cmdBuild.ConflictOption = ConflictOption.OverwriteChanges ' 所有的更新和删除语句仅在 WHERE 子句中包含 PrimaryKey 列
cmdBuild.SetAllValues = False ' update 语句中仅包含更改的列值
cmdBuild.DataAdapter = daUpdate
Try
UpdateDB = daUpdate.Update(dtChanged)
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
cmdBuild.Dispose()
daUpdate.Dispose()
End Function
DataAdapter 检查每次执行的插入、更新或删除操作所影响的行数,如果行数等于零,则引发DBConCurrencyException 异 常。而实际产生此异常的原因是:使用CommandBuilder为DataAdapter自动创建的更新Command,它们的Where子句包含了相 应表结构中的所有字段的比较,就是说,在更新一条记录之前,先通过比较所有的字段而不是仅通过主键的比较来查询这条记录,然后再更新。自从上次获取数据记 录之后,如果该数据记录被更新了,那么DataAdapter就会因为找不到该条记录而产生此异常。
一个较简单的解决方法是,设置CommandBuilder的相关属性:ConflictOption和SetAllValues。






















