【问题标题】:IDataAdapter and basic commands (insert, update, delete)IDataAdapter 和基本命令(插入、更新、删除)
【发布时间】:2016-06-21 16:20:26
【问题描述】:

我有一个将数据从 SQL 数据库绑定到 gridview 的函数。到目前为止,使用它效果很好:

    Dim dad As SqlDataAdapter
    Dim bs As BindingSource
    Dim dtb As DataTable
    Private Sub getDataSQL(ByVal selectCommand As String, ByVal connectionString As String)
        dtb = New DataTable
        Dim cnn As New SqlConnection(connectionString)
        cnn.Open()
        dad = New SqlDataAdapter(selectCommand, cnn)
        Dim basiccommands = New SqlCommandBuilder(dad)
        dad.InsertCommand = basiccommands.GetInsertCommand
        dad.UpdateCommand = basiccommands.GetUpdateCommand
        dad.DeleteCommand = basiccommands.GetDeleteCommand
        dad.Fill(dtb)
        bs = New BindingSource
        bs.DataSource = dtb
        navigator_main.BindingSource = bs 'this is a binding navigator
        dgv_main.DataSource = bs 'this is the main datagridview
        cnn.Close()
    End Sub

当用户添加/编辑/删除我调用的行时:

bs.EndEdit()
dad.Update(dtb)

现在我必须通过连接到不同类型的数据库(主要是 MySQL、ODB、SQL)来重用 getData 函数来填充 gridview。为此,我创建了一个接口,通过指示连接类型来允许重用许多功能:

Public Interface IDataBaseHelper
    Function openConnection(ByVal conn_string As String) As Boolean
    Function executeQuery(ByVal query As String) As IDataReader
    Function executeQuery(ByVal command As IDbCommand) As IDataReader
    Function executeNonQuery(ByVal query As String) As Integer
    Function createSQLCommand(ByVal query As String) As IDbCommand
    Function getDataAdapter(ByVal query As String) As IDataAdapter
    Sub closeConnection()
End Interface

新函数如下所示:

    Private mBindingSource As New BindingSource()
    Private mDataAdapter As IDataAdapter
    Private mDataSet As DataSet
    Private Sub getData(ByVal selectCommand As String, ByVal connectionString As String, ByVal connectionType As String)
        'Connection types are defined in FDataBaseHelper: FDataBaseHelper.SQLSERVER_ .MYSQL_ .ODBC_
        Dim cnn = FDataBaseHelper.createInstance(connectionType)
        cnn.openConnection(connectionString)
        mDataAdapter = cnn.getDataAdapter(selectCommand)
        mDataSet = New DataSet()
        Dim dtb As New DataTable
        mDataAdapter.Fill(mDataSet)
        dtb = mDataSet.Tables(0)
        mBindingSource.DataSource = dtb
        navigator_main.BindingSource = mBindingSource
        dgv_main.DataSource = mBindingSource
    End Sub

类 FDataBaseHelper 的样子:

Public Class FDataBaseHelper
    'Class factory depending on type of connection
    Public Const SQLSERVER_ = "SQLServer"
    Public Const MYSQL_ = "MySQL"
    Public Const ODBC_ = "ODBC"

    Public Shared Function createInstance(conn_type As String) As IDataBaseHelper
        If conn_type = SQLSERVER_ Then
            Return New DataBaseHelperSQL
        ElseIf conn_type = MYSQL_ Then
            Return New DataBaseHelperMySQL
        ElseIf conn_type = ODBC_ Then
            Return New DataBaseHelperODBC
        End If
        Return Nothing
    End Function

End Class

getDataAdapter 函数(例如用于 DataBaseHelperSQL)是:

Public Function getDataAdapter(query As String) As IDataAdapter Implements IDataBaseHelper.getDataAdapter
        Dim command = createSQLCommand(query)
        Dim adapter = New SqlDataAdapter(command)
        Return adapter
    End Function

datagridview 可以很好地填充,但用户所做的任何更改都不会存储在数据库中。问题是 IDataAdapter 没有 InsertCommand、UpdateCommand 和 DeleteCommand 作为成员,并且我收到错误:

mAdapter.Update(mDataSet)

错误提示:“在传递带有新行的 DataRow 集合时,更新需要有效的 InsertCommand” 我尝试了几种建议的解决方案,但无济于事,因为我没有发现有人使用界面来做这件事。 任何帮助将不胜感激

编辑:最终解决方案就像在帮助类中移动基本命令的定义一样简单。例如。对于 DataBaseHelperSQL,getDataAdapter 方法代表:

Public Function getDataAdapter(query As String) As IDataAdapter Implements IDataBaseHelper.getDataAdapter
        Dim command = createSQLCommand(query)
        Dim adapter = New SqlDataAdapter(command)
        Dim basiccommands = New SqlCommandBuilder(adapter)
        adapter.InsertCommand = basiccommands.GetInsertCommand
        adapter.UpdateCommand = basiccommands.GetUpdateCommand
        adapter.DeleteCommand = basiccommands.GetDeleteCommand
            Return adapter
End Function

【问题讨论】:

  • 缺少相当多的上下文,但是为了“记住”各种 DBCommand,需要持久化数据适配器(如第一个块中一样),您的 getDataAdapter 方法会创建一个 @ 987654330@ 还没有我不确定这样的事情有多“有用”,原因有以下几个:主要是那里有更多的代码,而不仅仅是直接使用 DB Providers;还有一些处置问题。
  • 所以你的意思是直接使用提供者会更好?我真的很想保留界面。我知道代码变得更加晦涩难懂,但我正在尝试构建具有一般功能的自定义控件,而不管数据库的类型如何。尽管如此,我会再考虑一下。谢谢!
  • 另一种方法是让 hist 应用程序构建一个已配置的数据适配器以供用户控件使用。问题仍然是每个数据库提供商都有的小怪癖。例如MySQL 将为您重新打开连接,而不是 OleDB 和 ODBC
  • 如您所说,通过预先配置数据适配器效果很好! (我怎么会错过呢?)。我明白你关于每个提供商的特殊性的观点。我想我会保留界面,直到遇到一些不可避免的问题。还是谢谢!

标签: vb.net


【解决方案1】:

最后,解决方案就像在帮助类中移动基本命令的定义一样简单。例如。对于 DataBaseHelperSQL,getDataAdapter 方法代表:

Public Function getDataAdapter(query As String) As IDataAdapter Implements IDataBaseHelper.getDataAdapter
        Dim command = createSQLCommand(query)
        Dim adapter = New SqlDataAdapter(command)
        Dim basiccommands = New SqlCommandBuilder(adapter)
        adapter.InsertCommand = basiccommands.GetInsertCommand
        adapter.UpdateCommand = basiccommands.GetUpdateCommand
        adapter.DeleteCommand = basiccommands.GetDeleteCommand
            Return adapter
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 2015-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多