更新时(此集合中已有一个名为“@xxxxxxx”的参数。)

问题描述 投票:0回答:0

我正在使用 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 工作,我必须“启动”并“提交”一个事务。

vb.net ado.net mysql-connector system.data
© www.soinside.com 2019 - 2024. All rights reserved.