1

请看下面的代码:

Public MustInherit Class clsType
        'Public Overridable Sub PopulateDataTable(ByVal columns As DataColumnCollection, ByRef objType As clsType, ByVal row As DataRow)
        Public Overridable Sub PopulateDataTable(ByVal columns As DataColumnCollection, ByVal row As DataRow)
            For Each column As DataColumn In columns
                Dim ColumnName As String = column.ColumnName
                Dim type As Type = Me.GetType
                Dim properties As PropertyInfo() = type.GetProperties()
                For Each PropertyInfo In properties
                    If PropertyInfo.Name = ColumnName Then
                        'Dim ColumnValue As String = row(ColumnName)
                        Dim PropertyInfo2 As PropertyInfo = Me.GetType().GetProperty(PropertyInfo.Name)
                        'PropertyInfo2.SetValue(Me, Convert.ChangeType(ColumnValue, PropertyInfo2.PropertyType), Nothing)
                        PropertyInfo2.SetValue(Me, Convert.ChangeType(row(ColumnName), PropertyInfo2.PropertyType), Nothing)
                        Exit For
                    End If
                Next
            Next
        End Sub

        Public Overridable Sub PopulateDataReader(ByVal objDR As DbDataReader)
            objDR.Read()
            For value As Integer = 0 To objDR.FieldCount - 1
                Dim ColumnName As String = objDR.GetName(value)
                Dim type As Type = Me.GetType
                Dim properties As PropertyInfo() = type.GetProperties()
                For Each PropertyInfo In properties
                    If PropertyInfo.Name = ColumnName Then
                        'Ship ship = new Ship();
                        'Dim ColumnValue As String = objDR.GetValue(value)
                        If IsDBNull(objDR.GetValue(value)) = False Then
                            Dim PropertyInfo2 As PropertyInfo = Me.GetType().GetProperty(PropertyInfo.Name)
                            PropertyInfo2.SetValue(Me, Convert.ChangeType(objDR.GetValue(value), PropertyInfo2.PropertyType), Nothing)
                        End If
                        Exit For
                    End If
                Next
            Next
        End Sub

    End Class

Public class TestType
    Inherits clsType
 Private _TestAttribute1 As Integer
 Private _TestAttribute2 As Integer

 Public Property TestAttribute1() As Integer
      Get
        Return _TestAttribute1
      End Get
      Set(ByVal value As Integer)
        _TestAttribute1 = value
      End Set
 End Property

Public Property TestAttribute2() As Integer
      Get
        Return _TestAttribute2
      End Get
      Set(ByVal value As Integer)
        _TestAttribute2 = value
      End Set
 End Property
End Class

我可以在使用数据传输对象的代码中执行类似的操作:

dim objTestType As new clsTestType
objTestType.PopulateDataReader(objDR)

objDR 是一个 .NET 数据阅读器。数据库中的列与类中的属性名称匹配。一旦上面的语句运行,对象 (objTestType) 就会被填充值。

我以前从未见过这样做过。这在架构(设计)和性能方面是不好的做法吗?即使用反射从DataReader/DataTable 填充对象?

4

1 回答 1

1

当您想要生成 ORM 时,以这种方式使用反射是一种可能性。有利有弊,但这本身并不是一个坏主意。

这段代码的缺点是性能,因为这实际上是传输数据的最慢的方式。这应该不足为奇,因为反射本质上是缓慢的,而且这是一个“幼稚”的直接实现,根本没有任何多余的装饰。

将 ORM 代码基于反射当然是可能的,但如果考虑性能,您将需要做得比这更好。我正在谈论的一个例子是使用Reflection.Emit在运行时根据来自反射的信息创建动态程序集;这将提高强类型代码附近的性能。

但是,这样做并正确执行将是很多工作。因此,如果性能很重要并且直接反射不会削减它,请考虑使用已建立的库,例如Emit Mapper

于 2013-09-18T19:44:53.087 回答