我正在使用 VB.NET、Visual Studio 2022、Win 10、MySQLConnector.dll (2.2.6.0) 我正在尝试将 MySQL 集成到一个框架中,该框架是 ADO.net 的包装器。让我尝试创建一些上下文。
这个框架最初是作为 AccessDB 的包装器,然后添加了 SQL Server。接下来是 SQLite、CSV、XLS、AS400 等。有一系列 case 语句为连接构建连接字符串。 然后创建所需的“DbProviderFactories”。 然后构建一个“DataTable”(dt)“DbCommand”(cmd)->“ExecuteReader”(reader as cmd.ExecteReader)->dt.Load(reader)。
主要代码
Dim tmp As clsDataTable = DataAccessIris.GetDT2("select * from ONLINEINFOAUX", "tmp", "MYSqlConnector",,, eErrReturn.Exception)
DispThis("Tmp: " & tmp.RowCount.ToString & NewLine)
tmp.LocalWalkFindRow(New Dictionary(Of String, Object) From {{"common_item_number", 50}})
tmp.Rows(tmp.LocalWalkFindRecordNum)("ONLINE_DESCRIPTION") = "test"
tmp.UpdateData()
clsDataTable 基于 .NET DataTable '.LocalWalkFindRow' 是一个循环遍历行查找匹配项并设置属性 'LocalWalkFindRecordNum' 的函数。
所有这些工作完成后,表格就已加载。我可以添加和删除记录。我可以访问行和字段。我可以更新行/字段。如果我显示行/字段,我可以看到更改。但是当我尝试更新表时,我得到了主题“错误,其中@xxxxx”是我试图更改的字段的名称中所述的内容。
更新内容类似于...
_da as Common.DbDataAdapter
来自通过 DbProviderFactories._da.Update(dt)
创建的内容
这里是更新功能。 “DataAccessIris”类有一个 open 语句。一旦打开,它就会存储在一个类型(String、DbDataAdapter)的数据字典中。传递的变量创建一个键,因此如果 DbDataAdapter 存在,则仅返回它,如果不存在,则它将被构建、存储,然后返回。
Public Sub UpdateData(Optional pSource As String = Nothing, Optional pDBnum As String = Nothing, Optional pStnum As String = Nothing, Optional DoUpdateEvent As Boolean = False)
If pSource Is Nothing Then pSource = Me._Source
If pDBnum Is Nothing Then pDBnum = Me._dbName
If pStnum Is Nothing Then pStnum = Me._stNum
Using _da As Common.DbDataAdapter = DataAccessIris.DBAdapter(pSource, pDBnum, pStnum, Me.Parms)
If TypeOf _da Is SqlDataAdapter Then
AddHandler CType(_da, SqlDataAdapter).RowUpdating, AddressOf DA_RowUpdating
If DoUpdateEvent Then AddHandler CType(_da, SqlDataAdapter).RowUpdated, AddressOf DA_RowUpdated
'ElseIf TypeOf _da Is SQLiteDataAdapter Then
' AddHandler CType(_da, SQLiteDataAdapter).RowUpdating, AddressOf DA_RowUpdating
' If DoUpdateEvent Then AddHandler CType(_da, SQLiteDataAdapter).RowUpdated, AddressOf DA_RowUpdated
ElseIf TypeOf _da Is Data.Odbc.OdbcDataAdapter Then
AddHandler CType(_da, Odbc.OdbcDataAdapter).RowUpdating, AddressOf DA_RowUpdating
If DoUpdateEvent Then AddHandler CType(_da, Odbc.OdbcDataAdapter).RowUpdated, AddressOf DA_RowUpdated
ElseIf TypeOf _da Is Data.OleDb.OleDbDataAdapter Then
AddHandler CType(_da, OleDb.OleDbDataAdapter).RowUpdating, AddressOf DA_RowUpdating
If DoUpdateEvent Then AddHandler CType(_da, OleDb.OleDbDataAdapter).RowUpdated, AddressOf DA_RowUpdated
End If
If DoUpdateEvent Then
_rowsToUpdate = 0
_rowsUpdated = 0
For xloop As Integer = 0 To Me.RowCount - 1
If Me.Rows(xloop).RowState <> DataRowState.Unchanged Then _rowsToUpdate += 1
Next
End If
Dim _trans As DbTransaction = Nothing
If _da.ToString = "System.Data.SQLite.SQLiteDataAdapter" Then
_trans = CType(DataAccessIris.OpenDb(pDBnum, pStnum).BeginTransaction, DbTransaction)
End If
_da.Update(Me)
If _trans IsNot Nothing Then
_trans.Commit()
_trans.Dispose()
End If
If Me.Parms IsNot Nothing Then
For x As Integer = 0 To Me.Parms.Count - 1
_da.SelectCommand.Parameters.Remove(Me.Parms(x))
Next
End If
End Using
blnSkipRowChange = True
Me.AcceptChanges()
MyBase.AcceptChanges()
blnSkipRowChange = False
SetInit()
End Sub
此 Pastebin 链接指向已构建的更新查询 https://pastebin.com/Mh1ESe0f
我可以提供更多细节,但我不想让这篇文章比我已经做的更令人困惑。 :-)
请告诉我什么可能有助于使其更清楚。
编辑 2023 年 7 月 31 日以清除参数的构建位置。还添加 System.Data 和 ADO.Net 标记以获取更多上下文。 DBAdapter 是 System.DataCommon.DbDataAdapter 的包装器。 这是代码...
Public Shared Function DBAdapter(ByVal CommandText As String,
Optional ByVal DataBaseName As String = "",
Optional ByVal StoreNumber As String = "",
Optional ByVal Prams() As DbParameter = Nothing) As DbDataAdapter
Dim da As DbDataAdapter = Nothing
Try
DataBaseName = DataBaseName.ToUpper
Dim conName As String = DataBaseName & StoreNumber
Dim cmd As DbCommand = Nothing
If Prams Is Nothing Then
cmd = DBCommand(CommandText, DataBaseName, StoreNumber)
Else
cmd = DBCommand(CommandText, Prams, DataBaseName, StoreNumber)
End If
'If DataBaseName.ToUpper.EndsWith(".SQLITE") Then
' da = New SQLiteDataAdapter
'Else
da = DbProviderFactories.GetFactory(dProviderTypes(conName)).CreateDataAdapter
'End If
da.SelectCommand = cmd
da.MissingSchemaAction = MissingSchemaAction.AddWithKey
Dim cmdBuild As DbCommandBuilder
'If DataBaseName.ToUpper.EndsWith(".SQLITE") Then
' cmdBuild = New SQLiteCommandBuilder
'Else
cmdBuild = DbProviderFactories.GetFactory(dProviderTypes(conName)).CreateCommandBuilder
'End If
cmdBuild.DataAdapter = da
Try
da.InsertCommand = cmdBuild.GetInsertCommand(True)
da.UpdateCommand = cmdBuild.GetUpdateCommand(True)
da.DeleteCommand = cmdBuild.GetDeleteCommand(True)
Catch
End Try
Return da
Catch ex As Exception
Throw New Exception(ex.Message & " Command Text='" & CommandText & "'", ex)
Finally
da = Nothing
End Try
End Function
上面的 Pastebin 链接 https://pastebin.com/Mh1ESe0f 就是 CommandBuilder.GetUpdateCommand(True) 所做的。
这里只是为了比较插入和删除。
CommandBuilder.GetInsertCommand(True) https://pastebin.com/pJUhYCiY
CommandBuilder.GetDeleteCommand(True) https://pastebin.com/Sg32Snmx
同样的包装器也用于 SQLite 和 SQL Server。要么我正在与一个错误作斗争,这会让我感到惊讶,因为我预计会有很多人使用 ADO.Net 和 MySQLConnector。一定有一些我没有预料到的细微差别。例如,为了让 SQLite 工作,我必须“启动”并“提交”一个事务。