【问题标题】:Reflection Optimization反射优化
【发布时间】:2015-11-26 00:15:19
【问题描述】:

我最近实现了反射,以取代从 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")
...

由于我的代码库有很多这样的功能,反射似乎是一个不错的选择,可以简化它并使未来的编码更容易。 How to assign datareader data into generic List ( of 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 here 似乎正是我想要的,但将其转换为 VB 会出现各种错误(使用 CodeFusion 或 converter.Telerik.com)。

以前有人在 VB 中做过这个吗?或者任何人都可以翻译最后一个链接中的内容吗?

感谢任何帮助。

【问题讨论】:

    标签: vb.net reflection


    【解决方案1】:

    给你几个想法。

    1. 一次读取所有记录时不要使用 DataReader,它比使用 DataAdapter 慢。
    2. 当您使用 DataAdapter 填充 DataSet 时,您可以遍历不使用反射的行和列,并且会更快。
    3. 我创建了一个程序(许多其他程序员也这样做),它为我从数据库生成代码。每个表和行都是一个专门命名为生成的类,这样我可以使用智能感知,并通过在数据更改时使它们成为编译时错误来防止许多运行时错误。这与 EntityFramework 非常相似,但更轻巧,因为它符合我的特定需求。

    【讨论】:

    • 谢谢。我将尝试数据适配器。对于第 3 点,您是否有可能将此代码张贴在某处或知道我可以查看的资源?
    • 对于第 3 点,这是我 15 年来构建的代码的巅峰之作,其中包含的不仅仅是该功能。任何程序员可以做的最好的事情之一就是创建程序来为您进行编程。 :-)
    猜你喜欢
    • 2011-04-30
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多