【VB.NET机房重构】数据传递----实体、DataTable、泛型

        一直不能理解我用着实体好好地,为什么非要换成DataTable,问别人的结果是:因为泛型特别好使。我就纳闷了,这又跟泛型有什么关系。问了好多都不是我要的结果,牛角尖上来了,那就自己搜索资料理解吧。

首先说:为什么要用实体?

         对于大量的数据来说,还向VB版机房收费那样定义变量做参数显然是不合适的,一些简单的窗体还好,如登录窗体,就两个字段;要是换做注册窗体,起码得有十几个变量,很容易造成参数匹配上的错误,而且每次增删改查还要传递十几个参数,简直是麻烦透了。

          为此,我们引入了实体。实体对应的不是数据库中的单个字段,而是整张表。通过抽象封装,将每个表中的字段作为一个类的属性封装在指定的一个实体中。这样传递数据的时候,我们只传递一个实体就可以啦,当你需要哪个字段的时候,通过get()set()就可以啦,这样明显比一大堆参数飘来飘去整齐的多,灵活性增强,安全性增强,便于维护和拓展。(当然,如果是一两个字段,那传参数和传实体是一样的啦)

再说:DataTable

          一直以为实体是对变量型参数的升级,而DataTable是对实体的升级。其实大错特错。其实用过DataTable之后就会感觉出来,DataTable是一个虚拟表,这个表跟数据库的紧密相当密切,虚拟表中的每个字段分别对应每个数据库表中的字段。而DataTable跟实体有什么联系呢?从数据库中查到的数据其实是默认存放到DataTable虚拟表中的,我们知道了实体的好处,所以通过反射将DataTable中的字段封装成实体对象后返回。换句话来说,实体的来源就是DataTable进行属性的反射得到的。所以,从面向对象角度说,实体是DataTable的升级。DataTable是一个虚拟表,更致力于表中的字段,可以直接进行字段的运算啊什么的比较方便,字段操作的灵活性比较强,性能比较好。

最后说:为什么使用泛型?

         泛型结合类可以将类型参数用做它所存储的对象的类型的占位符。类型参数作为其字段的类型和其方法的参数类型出现。这样说可能有些抽象,用图来表示吧。个人觉得这张图最好不过,就直接引用不做修改了。

【VB.NET机房重构】数据传递----实体、DataTable、泛型_第1张图片

        可以说,泛型是在实体上进一步的封装,以实体为参数形成集合。这样一个泛型集合中,就可以最大容量的反应数据库,可以方便多张表的操作。

       以简单的BasicData表的查询为例。首先写一个DataTable转换成泛型的类:ConvertHelper。代码如下:

Imports System.Collections.Generic  '增加泛型的命名空间    
Imports System.Reflection '引入反射  
Public Class ConvertHelper
    '将datatable转化为泛型集合    
    Public Shared Function convertToList(Of Turn As {New})(ByVal dt As DataTable) As IList(Of Turn)
        'convertToList(Of Turn As {New}) 这里的new是用来约束T的   

        Dim myList As New List(Of Turn)   '定义最终返回的集合    
        Dim myTpye As Type = GetType(Turn) '得到实体类的类型名    
        Dim dr As DataRow   '定义行集    
        Dim tempName As String = String.Empty   '定义一个临时变量    

        '遍历DataTable的所有数据行    
        For Each dr In dt.Rows

            Dim myTurn As New Turn    '定义一个实体类的对象    
            Dim propertys() As PropertyInfo = myTurn.GetType().GetProperties()  '定义属性集合    
            Dim Pr As PropertyInfo

            '遍历该对象的所有属性    
            For Each Pr In propertys
                tempName = Pr.Name '将属性名称赋值给临时变量    
                If (dt.Columns.Contains(tempName)) Then     '将此属性与datatable里的列名比较,查看datatable是否包含此属性    
                    '判断此属性是否有Setter    
                    If (Pr.CanWrite = False) Then   '判断此属性是否可写,如果不可写,跳出本次循环    
                        Continue For
                    End If
                    Dim value As Object = dr(tempName)  '定义一个对象型的变量来保存列的值    
                    If (value.ToString <> DBNull.Value.ToString()) Then '如果非空,则赋给对象的属性    
                        Pr.SetValue(myTurn, value, Nothing)    '在运行期间,通过反射,动态的访问一个对象的属性    
                    End If
                End If
            Next
            myList.Add(myTurn)   '添加到集合    
        Next
        Return myList   '返回实体集合    
    End Function
End Class
具体的D层调用如下:

     ''' <summary>
    ''' 查询BasicData并显示
    ''' </summary>
    ''' <param name="basicdataentity"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SelectBasicData(ByVal basicdataentity As Entity.BasicDataEntity) As List(Of Entity.BasicDataEntity)
        Dim sql As New SQLHelper.SqlHelper
        Dim dt As DataTable
        Dim mylist As List(Of Entity.BasicDataEntity)

        Dim strsql As String = "Select * from BasicData " '定义SQL语句

        dt = sql.ExecSelectNo(strsql, CommandType.Text)
        mylist = ConvertHelper.convertToList(Of Entity.BasicDataEntity)(dt)
        Return mylist
    End Function
小结:

         从DataTable到实体,再到泛型,一步一步更接近面向对象。但是具体怎么用,用什么,三个数据传递方式各有千秋。


你可能感兴趣的:(代码,数据,VB.NET,三层)