2

有人能解释一下我们在将数据库连接到 VB 时使用的这两个函数或它背后的原理吗?该代码来自我们的老师,我们的老师没有解释为什么要这样编码。我们正在为数据库使用 MS Access 2003 文件。

Imports System.Data.OleDb

Public Class Form1
    Dim dbPath As String = Application.StartupPath & "\Database\xxxx.mdb"
    Dim connectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0; DATA SOURCE = " & dbPath

    Private Function performQuery(ByRef connectionString As String, ByVal sqlCommand As String) As OleDb.OleDbDataReader
        Dim dbConnection As OleDbConnection
        Dim dbCommand As New OleDbCommand()
        Dim dbDataReader As OleDb.OleDbDataReader = Nothing
        Try
            dbConnection = New OleDbConnection(connectionString)
            dbCommand.CommandText = sqlCommand
            dbCommand.Connection = dbConnection
            dbConnection.Open()
            dbDataReader = dbCommand.ExecuteReader
            Return dbDataReader
            dbConnection.Close()
        Catch ex As Exception
            MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End Try
        Return Nothing
    End Function

    Private Function performNonQuery(ByVal connectionString As String, ByVal sqlCommand As String) As Boolean
        Dim dbConnection As OleDbConnection
        Dim dbCommand As New OleDbCommand()
        Try
            dbConnection = New OleDbConnection(connectionString)
            dbCommand.CommandText = sqlCommand
            dbCommand.Connection = dbConnection
            dbCommand.Connection.Open()
            dbCommand.ExecuteNonQuery()
            dbConnection.Close()
        Catch ex As Exception
            MessageBox.Show(ex.Message, Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return False
        End Try
        Return True
    End Function
End Class
4

2 回答 2

1

performQuery功能有问题。它永远不会关闭连接(Return dbDataReader发生在连接关闭之前)。一方面 - 这是一件好事,因为 DataReader 在没有开放连接的情况下是无用的。另一方面 - 连接作为函数内部的私有变量打开,因此当函数返回时它超出范围,您永远不知道垃圾收集器何时决定收集它。当这发生在 Reader.Read 的中间时总是很有趣。

于 2013-09-13T17:11:29.817 回答
1

将连接与执行分开是个好主意,这样概念就不会那么混乱。

这里的第一个概念是使用连接字符串建立到数据库的连接。但是由于 OleDbConnection 占用了系统资源,因此无论是否发生异常,都需要正确处理处理它的变量。这就是连接变量上的 Intellisense 告诉您 .Dispose() 是其中一种方法的原因。

Using cnn As OleDbConnection = New OleDbConnection(connectionString)
cnn.Open()
.
.
.
cnn.Close
End Using

这里的第二个概念是当您与数据库建立开放连接时,您可以使用它打开一个 OleDbCommand 对象,这允许您(a)使用 SELECT 通过您的“performQuery”方法从数据库中读取某些内容,或者( b) 通过“performNonQuery”方法对数据库表执行一些操作,使用 SQL 关键字,例如 UPDATE、DELETE 或 INSERT。

Using cmd As New OleDbCommand(sqlCommand, cnn)
' Use cnn.ExecuteReader() to get a data reader back,  
' or use cnn.ExecuteNonQuery() to get the number of rows affected back.
.
.
.
End Using

第三,如果您要返回信息,通常它会返回一个矩形数据,可以通过使用 OleDbDataReader 对象逐行遍历。但是数据读取器作为返回参数是无用的,因为它会使连接保持打开状态,并且还会使数据库游标指向当前行。那不好!

最好只返回表格形状的内存中的数据,例如 DataTable 对象:

dim dt as DataTable = new DataTable("TableName")
Using cnn As OleDbConnection = New OleDbConnection(connectionString) 
cnn.Open() ' open the connection
Using cmd As New OleDbCommand(sqlCommand, cnn) ' make a command object
dr = cmd.ExecuteReader() ' execute the reader
dt.Load(dr) ' BAM - get all the data into the DataTable at once
End Using ' close everything up
Return dt

我认为这可以解释一些事情。

于 2013-09-13T23:46:18.080 回答