Vb.net IDataAdapter和基本命令(插入、更新、删除)
我有一个将SQL数据库中的数据绑定到gridview的函数。到目前为止,使用以下方法效果良好:Vb.net IDataAdapter和基本命令(插入、更新、删除),vb.net,Vb.net,我有一个将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 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)
现在,我必须重用getData函数,通过连接到不同类型的数据库(主要是MySQL、ODB、SQL)来填充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
其中clase 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)是:
datagridview填充得很好,但用户所做的任何更改都不会存储在数据库中。问题是IDataAdapter没有InsertCommand、UpdateCommand和DeleteCommand作为成员,我在以下方面遇到了一个错误:
mAdapter.Update(mDataSet)
错误为:“当用新行传递DataRow集合时,更新需要有效的InsertCommand”
我已经尝试了几种建议的解决方案,但都没有效果,因为我还没有发现有人使用接口。
任何帮助都将不胜感激
编辑:最后,解决方案非常简单,只需将基本命令的定义移动到helper类中即可。例如,对于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
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
最后,解决方案非常简单,只需将基本命令的定义移动到helper类中即可。例如,对于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
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
最后,解决方案非常简单,只需将基本命令的定义移动到helper类中即可。例如,对于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
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,需要持久化dataadapter(如第一个块中所示),您的
getDataAdapter
方法创建了一个新的SqlDataAdapter
,但它没有任何内容,我不确定它是否“有用”这样的事情有几个原因:主要是那里有比直接使用DB提供者更多的代码;还有一些处理问题。那么你的意思是直接使用提供商会更好?我真的很想保留这个界面。我知道代码变得越来越模糊,但我正在尝试构建一个具有常规功能的自定义控件,而不管DB的类型如何。尽管如此,我还是要重新考虑一下。谢谢hist应用程序也可以为要使用的用户控件构建配置的dataadapter。问题仍然是每个DB提供商都有一些小的古怪之处。e、 通过预先配置dataadapter,MySQL将为您重新打开连接,而不是像您所说的OleDB和ODBC,效果非常好!(我怎么会错过呢?)。我明白你关于每个供应商的特殊性的观点。我想我会保留这个界面,直到遇到一些不可避免的问题。无论如何谢谢你!有相当数量的上下文缺失,但为了“记住”各种DBCommand,需要持久化dataadapter(如第一个块中所示),您的getDataAdapter
方法创建了一个新的SqlDataAdapter
,但它没有任何内容,我不确定它是否“有用”这样的事情有几个原因:主要是那里有比直接使用DB提供者更多的代码;还有一些处理问题。那么你的意思是直接使用提供商会更好?我真的很想保留这个界面。我知道代码变得越来越模糊,但我正在尝试构建一个具有常规功能的自定义控件,而不管DB的类型如何。尽管如此,我还是要重新考虑一下。谢谢hist应用程序也可以为要使用的用户控件构建配置的dataadapter。问题仍然是每个DB提供商都有一些小的古怪之处。e、 通过预先配置dataadapter,MySQL将为您重新打开连接,而不是像您所说的OleDB和ODBC,效果非常好!(我怎么会错过呢?)。我明白你关于每个供应商的特殊性的观点。我想我会保留这个界面,直到遇到一些不可避免的问题。无论如何谢谢你!