我最近实现了反射,以取代从SQL数据库检索数据的更乏味的方面。旧代码看起来像这样:
_dr = _cmd.ExecuteReader (_dr is the SQLDataReader)
While _dr.Read (_row is a class object with public properties)
_row.Property1 = Convert.ToInt16(_dr("Prop1"))
_row.Property2 = Convert.ToInt16(_dr("Prop2"))
_row.Property3 = Convert.ToInt16(_dr("Prop3"))
If IsDBNull(_dr("Prop4")) = False Then _row.Prop4 = _dr("Prop4")
...
由于我的代码库有很多这样的功能,反射似乎是简化它并使未来的编码更容易的好方法。如何将数据读取器数据分配到(T的)泛型列表中有一个很好的答案,它实际上像魔术一样满足了我的需求,并很容易翻译成VB
Public Shared Function GenericGet(Of T As {Class, New})(ByVal reader As SqlDataReader, ByVal typeString As String)
'Dim results As New List(Of T)()
Dim results As Object
If typeString = "List" Then
results = New List(Of T)()
End If
Dim type As Type = GetType(T)
Try
If reader.Read() Then
' at least one row: resolve the properties
Dim props As PropertyInfo() = New PropertyInfo(reader.FieldCount - 1) {}
For i As Integer = 0 To props.Length - 1
Dim prop = type.GetProperty(reader.GetName(i), BindingFlags.Instance Or BindingFlags.[Public])
If prop IsNot Nothing AndAlso prop.CanWrite Then
props(i) = prop
End If
Next
Do
Dim obj = New T()
For i As Integer = 0 To props.Length - 1
Dim prop = props(i)
If prop Is Nothing Then
Continue For
End If
' not mapped
Dim val As Object = If(reader.IsDBNull(i), Nothing, reader(i))
If val IsNot Nothing Then SetValue(obj, prop, val)
Next
If typeString = "List" Then
results.Add(obj)
Else
results = obj
End If
Loop While reader.Read()
End If
Catch ex As Exception
Helpers.LogMessage("Error: " + ex.Message + ". Stacktrace: " + ex.StackTrace)
End Try
Return results
End Function
唯一需要注意的是速度有些慢。
我的问题是如何优化。我在网上找到的示例代码都是C#,不能很好地转换成VB。这里的场景4似乎正是我想要的,但将其转换成VB会出现各种错误(使用CodeFusion或converter.Telerik.com)。
以前有人在VB中这样做过吗?或者有人能翻译最后一个链接中的内容吗?
感谢您的帮助。
为您提供一些想法。
- 一次读取所有记录时不要使用DataReader,它比使用DataAdapter慢
- 当您使用DataAdapter填充数据集时,您可以遍历不使用反射的行和列,这样会更快
- 我有一个我创建的程序(许多其他程序员也这样做),它为我从数据库中生成代码。每个表和行都是一个专门命名为的类。我可以使用intellisense,并通过在数据更改时使它们编译时出错来防止许多运行时错误。这很像EntityFramework,但更轻,因为它符合我的特定需求