问题
Currently, I am using a SqlDataReader
loaded up with a simple database 'Select' query. Each row represents a domain object, so I inflate each object like this:
Dim loadedItems As New List(Of Item)
Dim dr As SqlDataReader = GetItemsDataReader()
While dr.Read()
Dim item As Item = GetItemFromData(dr)
loadedItems.Add(item)
End While
The GetItemFromData
method I wrote looks something like this:
Private Function GetItemFromData(dr As SqlDataReader) As Item
Dim loadedItem As New Item()
loadedItem.ID = dr("ID")
loadedItem.Name = dr("Name")
'etc., etc.'
Return loadedItem
End Function
In some cases, I have to read data from a DataRow
instead of a SqlDataReader
. But the code would be the exact same! As I look at my GetItemFromData
method, I want to accept a more generic type of object in the dr
parameter so that I can treat a DataReader
the same as a DataRow
, since I would be writing the exact same code inside the method if I wrote one that was meant to use a DataRow
. Is there a way to do that?
回答1:
Only way I can think of off the top of my head would be to wrap a few classes and implement an inferface - something like:
Interface IIndexer
Default ReadOnly Property Item(ByVal index As String)
End Interface
Class DataReaderWrapper
Implements IIndexer
Private ReadOnly _reader As IDataReader
Public Sub New(reader As IDataReader)
_reader = reader
End Sub
Public ReadOnly Property Item(index As String) As Object Implements IIndexer.Item
Get
Return _reader(index)
End Get
End Property
End Class
Class DataRowWrapper
Implements IIndexer
Private ReadOnly _row As DataRow
Public Sub New(row As DataRow)
_row = row
End Sub
Public ReadOnly Property Item(index As String) As Object Implements IIndexer.Item
Get
Return _row(index)
End Get
End Property
End Class
You would then have to wrap your row or reader before passing it to your method:
Private Function GetItemFromData(indexer As IIndexer) As Item
Dim loadedItem As New Item()
loadedItem.ID = indexer("ID")
loadedItem.Name = indexer("Name")
'etc., etc.'
Return loadedItem
End Function
Dim i As Item = GetItemFromData(New DataRowWrapper(dr))
回答2:
How about using a DataTable
instead:
Dim DataTable table AS new DataTable()
table.Load(GetItemsDataReader())
foreach (DataRow row in table.Rows) {
Dim item As Item = GetItemFromData(row)
loadedItems.Add(item)
}
Change your GetItemFromData() method to take a DataRow
instead of a DataReader
(sorry about the VB.NET/C# hybrid pseudo code).
来源:https://stackoverflow.com/questions/7666943/how-can-i-read-from-a-datarow-or-a-datareader-using-the-same-code