为什么SQLHelper.vb中没有 ExecuteDataTable 的共享函数。有一个:ExecuteReader、ExecuteDataset 和 ExecuteScaler。
这不是问题,因为我会自己写。我只是在徘徊为什么会这样。我通常会使用 DataReader,但我正在编写数据逻辑层,并且 DataTable 需要超过连接(DataReaders 不能超过连接)。
为什么SQLHelper.vb中没有 ExecuteDataTable 的共享函数。有一个:ExecuteReader、ExecuteDataset 和 ExecuteScaler。
这不是问题,因为我会自己写。我只是在徘徊为什么会这样。我通常会使用 DataReader,但我正在编写数据逻辑层,并且 DataTable 需要超过连接(DataReaders 不能超过连接)。
ExecuteDataset()
已经做了你需要的。从某种意义上说,数据集只是 DataTables 的集合。
我通常会使用 DataReader,但我正在编写一个数据逻辑层,并且 DataTable 需要超过连接(DataReaders 不能超过连接)。
在这种情况下,我可以建议您构建一个ExecuteEnumerable()
在 Iterator 块中使用 DataReader 的方法,而不是构建一个 ExecuteDatatable() 方法。代码看起来像这样:
Public Shared Iterator Function ExecuteEnumerable(Of T)( ... ) As IEnumerable(Of T)
Using cn As New SqlConnection( ... ), _
cmd As New SqlCommand( ... )
'As needed
'cmd.Parameters.Add( ... ).Value = ...
Using rdr As SqlDataReader = cmd.ExecuteReader()
While rdr.Read()
Yield transform(rdr)
End While
End Using
End Using
End Function
你会注意到我跳过了一些事情。我不熟悉现有的 SqlHelper.vb 文件,因为您希望匹配现有样式,所以我在代码中留出了空间供您适应。但是,我想指出两个重要的部分:
transform(rdr)
调用将使用Func(IDataRecord, T)
必须作为参数提供给函数的委托。要使 ExecuteEnumerable() 迭代器概念起作用,您必须在每次迭代时获取 SqlDataReader 对象中当前值的副本。您可以在此处设置某种通用数据传输对象,就像在 DataTable 中使用 DataRow 类型一样。但是,与其花费 cpu 和内存时间将副本创建到某种类型的通用数据传输对象中,我更喜欢使用委托让代码将其直接复制到强类型业务对象中。缺点是需要在每次调用方法时发送有关如何为您的特定对象执行此操作的说明。不过,大多数情况下,使用业务对象上的共享工厂方法很容易做到这一点。我们可以像 DataSet 一样创建
' Execute a SqlCommand (that returns a resultset) against the specified SqlConnection
' using the provided parameters.
' e.g.:
' Dim dt As DataTable = ExecuteDataTable(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24))
' Parameters:
' -connection - a valid SqlConnection
' -commandType - the CommandType (stored procedure, text, etc.)
' -commandText - the stored procedure name or T-SQL command
' -commandParameters - an array of SqlParamters used to execute the command
' Returns: A dataset containing the resultset generated by the command
Public Overloads Shared Function ExecuteDataTable(ByVal connection As SqlConnection, _
ByVal commandType As CommandType, _
ByVal commandText As String, _
ByVal ParamArray commandParameters() As SqlParameter) As DataTable
If (connection Is Nothing) Then Throw New ArgumentNullException("connection")
' Create a command and prepare it for execution
Dim cmd As New SqlCommand
Dim dt As New DataTable
Dim dataAdatpter As SqlDataAdapter
Dim mustCloseConnection As Boolean = False
PrepareCommand(cmd, connection, CType(Nothing, SqlTransaction), commandType, commandText, commandParameters, mustCloseConnection)
Try
' Create the DataAdapter & DataSet
dataAdatpter = New SqlDataAdapter(cmd)
' Fill the DataSet using default values for DataTable names, etc
dataAdatpter.Fill(dt)
' Detach the SqlParameters from the command object, so they can be used again
cmd.Parameters.Clear()
Finally
If (Not dataAdatpter Is Nothing) Then dataAdatpter.Dispose()
End Try
If (mustCloseConnection) Then connection.Close()
' Return the dataset
Return dt
End Function ' ExecuteDataTable