vb.net环境下将DataTable转成泛型集合方法

 

背景

       做机房收费系统的时候,遇到这样一个问题,将数据库表中的数据取出一行,将每个单元格中的内容填充到窗体

文本框中。考虑到用DataReader获取结果的复杂性,我就用了泛型集合。可是这么一用却出现了如图所示的问

题。

问题一:

       出现这种问题,是因为在DataTable转实体类型时表的字段类型和实体的字段类型不一致造成的。 这个也可以

这么说,中国人的孩子都随父姓,这是传统。但孩子随母姓,就有些不妥。

 技术分享

 

 

问题二:

            数据库表中字段名和要转换的实体属性字段名不一致,导致转换后实体中depart为空值。

技术分享技术分享

 

转换原理

       分析:出现这些问题原因是我不太懂DataTable转实体类型的原理。经过查资料,加上自己的理解,终于将这种

转化方法掌握了,在敲代码时省了不少的功夫。 先看转换过程原理图。

       原理:数据库表中每行数据都先转化成一个实体类,然后将转化好的实体类放入泛型集合中

技术分享

 

泛型集合应用

 

实现功能:

       将数据库表中数据分别加载到对应窗体文本框中                

技术分享

 

代码实现

(1)在实体层建一个实体转换过程

'***************************************************
'说明:泛型集合,完成datatable类型转换为实体类
'作者:王聚
'创建日期:2014-04-24 11:08:02
'版本号:V1.00
'***************************************************
Imports System.Collections.Generic
Imports System.Reflection

Public Class EntityMoudule

    '将datatable转换为泛型集合
    Public Shared Function converToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)

        Dim mylist As New List(Of T)         '定义最终返回的集合
        Dim mytype As Type = GetType(T)      '得到实体类的类型名

        Dim dr As DataRow                    '定义行集
        Dim TmpName As String = String.Empty '定义一个临时变量

        '遍历datatable的所有数据行
        For Each dr In dt.Rows
            Dim myT As New T    '定义一个实体类对象
            Dim propertys() As PropertyInfo = myT.GetType().GetProperties() '定义属性集合
            Dim pr As PropertyInfo

            '遍历该对象的所有属性
            For Each pr In propertys
                TmpName = pr.Name   '将属性名称赋值给全局变量

                '检查datatable是否包含此列,列名==对象的属性名

                If (dt.Columns.Contains(TmpName)) Then  '将此属性与datatable的列名比较,查看datatable是否包含此属性

                    '判断此属性是否有setter类
                    If (pr.CanWrite = False) Then   '判断此属性是否可写,如果不可写,跳出此循环

                        Continue For
                    End If

                    Dim value As Object = dr(TmpName)   '定义一个对象的列来保存列的值

                    If (value.ToString <> DBNull.Value.ToString()) Then '判断是否为空,如果非空,则赋给对象的属性

                        pr.SetValue(myT, value, Nothing)    '在运行期间通过反射,动态的访问一个动态的属性

                    End If
                End If
            Next
            mylist.Add(myT) '将myT对象添加到集合
        Next
        Return mylist   '返回实体集合
    End Function
End Class


(2)在D层中实现代码

Public Class BasicDataBLL
    

    Public Function BasicDataList() As IList(Of Entity.BasicDataEntity)

        Dim Ibasicdata As IDAL.IBasicData
        Dim factory As New Factory.BasicDataFac
        Ibasicdata = factory.CreateIbasicdata()

        Dim mylist As IList(Of Entity.BasicDataEntity)
        mylist = Ibasicdata.SetDataList()

        Return mylist


    End Function
End Class

 

(3)接口层,定义一个接口

Public Interface IBasicData

    Function SetDataList() As IList(Of Entity.BasicDataEntity)
End Interface

 

(4)工厂层,创建一个接口

Public Class BasicDataFac
    Dim AssemblyName As String = "DAL"
    Dim db As String = ConfigurationSettings.AppSettings("DB")

    Function CreateIbasicdata() As IBasicData
        Dim Ibasicdata As IBasicData
        Ibasicdata = CType(Assembly.Load(AssemblyName).CreateInstance(AssemblyName + "." + db + "BasicDataDAL"), IBasicData)
        Return Ibasicdata
    End Function
End Class


 

(5)在B层中访问D层接口方法

Public Class BasicDataBLL


    Public Function BasicDataList() As IList(Of Entity.BasicDataEntity)

        Dim Ibasicdata As IDAL.IBasicData
        Dim factory As New Factory.BasicDataFac
        Ibasicdata = factory.CreateIbasicdata()

        Dim mylist As IList(Of Entity.BasicDataEntity)
        mylist = Ibasicdata.SetDataList()

        Return mylist


    End Function
End Class


(6)外观层,接收B层中的泛型集合

Public Class BasicDataFacade

    Public Function BasicDatalist() As IList(Of Entity.BasicDataEntity)
        Dim mylist As IList(Of Entity.BasicDataEntity)
        Dim setdata As New BLL.BasicDataBLL
        mylist = setdata.BasicDataList()

        Return mylist

    End Function
End Class

(7)U层,将泛型集合中数据填充到窗体中

    Private Sub frmSetBasic_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        cmdCommit.Enabled = False   '使确定按钮不能用
        GroupBox1.Enabled = False   '数据不可修改
        cmdCancle.Enabled = False   '取消不可用

        'Dim mylist As IList(Of Entity.BasicDataEntity)
        Dim loaddata As New Facade.BasicDataFacade

        mylist = loaddata.BasicDatalist()

        Dim num As Integer
        num = mylist.Count - 1     'num表示表中最后一行

        txtFixed.Text = mylist(num).FixedUser
        txtCasual.Text = mylist(num).CasualUser
        txtIncrease.Text = mylist(num).IncrementOfTime
        txtAtLeast.Text = mylist(num).AtLeastTime
        txtPrepare.Text = mylist(num).PrepareTime
        txtLeast.Text = mylist(num).MinCharge

    End Sub

(8)实体类型属性

Public Class BasicDataEntity

    '一般用户属性
    Private _userId As String
    Public Property UserId As String
        Get
            Return _userId
        End Get
        Set(value As String)
            _userId = value
        End Set
    End Property

    '最少金额属性
    Private _minCharge As Decimal
    Public Property MinCharge As Decimal
        Get
            Return _minCharge
        End Get
        Set(value As Decimal)
            _minCharge = value
        End Set
    End Property

    '准备时间属性
    Private _prepareTime As Integer
    Public Property PrepareTime As Integer
        Get
            Return _prepareTime
        End Get
        Set(value As Integer)
            _prepareTime = value
        End Set
    End Property


    '最少上机时间属性
    Private _atleastTime As Integer
    Public Property AtLeastTime As Integer
        Get
            Return _atleastTime
        End Get
        Set(value As Integer)
            _atleastTime = value
        End Set
    End Property


    '单位递增时间属性
    Private _incrementOfTime As Integer
    Public Property IncrementOfTime As Integer
        Get
            Return _incrementOfTime
        End Get
        Set(value As Integer)
            _incrementOfTime = value
        End Set
    End Property


    '固定用户属性
    Private _fixedUser As Decimal
    Public Property FixedUser As Decimal
        Get
            Return _fixedUser
        End Get
        Set(value As Decimal)
            _fixedUser = value
        End Set
    End Property


    '临时用户属性
    Private _casualUser As Decimal
    Public Property CasualUser As Decimal
        Get
            Return _casualUser
        End Get
        Set(value As Decimal)
            _casualUser = value
        End Set
    End Property

End Class


 

 

总结

        泛型转化相对于DataReader处理数据简单化了,对数据的可操作性强,即在D层进行转化后,不管到那个层都

可以读取数据,优化代码结构,使业务逻辑简单化。

 

 

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。