[置顶] 个人机房重构——DataTable与泛型的应用

          个人机房重构的过程中,我们接触到了DataTable和泛型,对于这两种数据类型,各有自己的优缺点,结合机房收费系统中的应用和借鉴的资料,总结整理分享给大家。

DataTable

       DataTable 是一个临时保存数据的网格虚拟表(表示内存中数据的一个表。DataTable是ADO dot net 库中的核心对象。它可以被应用在 VB 和 ASP 上。它无须代码就可以简单的绑定数据库。它具有微软风格的用户界面。

 优点

     DataTable是一个非常好用的用于临时保存数据的表格的数据类型。对于处理数据量小的系统具有很好的方便性和易用性,由于DataTable保存的数据表一定程度上反映了数据库中数据表的一定样子,使得数据的展现更加直观和高效率。而且与DataGridView控件的结合,充分的展现了它的实用性。

如图:

[置顶] 个人机房重构——DataTable与泛型的应用_第1张图片


缺点

        正如刚才所说,DataTable是一个存储数据的虚拟表,会占用一定的内存,但当数据量无比巨大时,就会导致DataTable的崩溃,致使系统无法正常使用。其次,DataTable读取数据库数据时,必须要了解数据库数据的结构,给编程带来了一定的风险,一旦数据库修改,则意味着系统也必须同时修改,这不符合面向对象的编程思想。而且DataTable为弱类型,无法直观的看出字段的数据类型。

我们结合代码来分析:

 '填充文本框
        txtStudentNo.Text = dt.Rows(0).Item(2)
        txtName.Text = dt.Rows(0).Item(3)
        txtSex.Text = dt.Rows(0).Item(4)
        txtTie.Text = dt.Rows(0).Item(5)
        txtGrade.Text = dt.Rows(0).Item(6)
        txtClass.Text = dt.Rows(0).Item(7)
        txtStatus.Text = dt.Rows(0).Item(11)
        txtExplain.Text = dt.Rows(0).Item(9)
        txtBalance.Text = dt.Rows(0).Item(8)

如上面的代码所示,每个文本框所绑定的是具体的某一行某一列的数据,一对一的绑定关系,一旦修改数据库字段的顺序,就会导致系统显示信息的错误,这更像是面向过程的编程方式。


泛型

        泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写  体验泛型代码时定义一些可变部份,那些部份在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。

优点

        使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能,不必了解数据库结构,符合面向对象思想,实体类的属性是强类型,每个字段的类型都是已知的。泛型最常见的用途是创建集合类。具备可重用性、类型安全和效率。

为实现同样的功能 ,我们看一看使用泛型的代码:

'查询后的显示到窗体上
            txtStudentNo.Text = myList(0).StudentNo
            txtState.Text = myList(0).Status
            txtBalance.Text = myList(0).Cash
            txtDepart.Text = myList(0).Department
            txtGrade.Text = myList(0).Grade
            txtClass.Text = myList(0).Sclass
            txtSex.Text = myList(0).Sex
            txtState.Text = myList(0).Status
            txtRemark.Text = myList(0).Remark
            txtName.Text = myList(0).StudentName

缺点

         泛型的缺点就是在性能上不如数组快,当然,相对来说而已。

DataTable转泛型

          因为我们在机房收费系统的时候有多个查询功能,而我们通过Sqlhelper类返回的都是DataTable,所以我们需要多次进行泛型集合的转换,为了体现代码的复用,我们将这个转换的方法抽象出单独的一个类放在D层,以供调用。
'**********************************************   
' 文  件  名:ConvertGenericsHelper   
' 命名空间:DAL   
' 内       容:   
' 功       能:   将Datatable转换为泛型
' 作       者:王洪玉 
' 小       组:王洪玉
' 生成日期:2016/2/13 20:06:17   
' 版  本  号:V1.0.0.0   
' 修改日志:   
'********************************************** 

Imports System.Collections.Generic   '增加泛型的命名空间
Imports System.Reflection  '引入反射,为了使用PorpertyInfo

Public Class ConvertGenericsHelper
    '将datatable转换为泛型集合
    Public Shared Function convertToGenerics(Of T As {New})(ByVal dt As DataTable) As IList(Of T)
        '注意:这里的New是用来约束T的,必须要有,不然new T的时候会出现错误
        Dim myGenerics As New List(Of T)   '定义最终返回的集合

        Dim myType As Type = GetType(T) '得到实体类的类型名
        Dim dr As DataRow                 '定义行集

        Dim tempName As String = String.Empty

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

            For Each Pr In propertys          '遍历该对象的所有属性
                tempName = Pr.Name            '将属性名称赋值给临时变量


                '检查DataTable是否包含此列(列名==对象的属性名)
                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(myT, value, Nothing)               '在运行期间,通过反射,动态的访问一个对象的属性
                    End If

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


在D层的调用
 '先判断dt是否为空
        If dt.Rows.Count > 0 Then
            '将dt转换为泛型集合
            myList = ConvertGenericsHelper.convertToGenerics(Of Entity.EN_StudentInfo)(dt)
            Return myList
        Else
            Return Nothing
        End If

应用

DataTable与DataGridView的结合

DataGridView控件一款非常强大的数据处理的表格类型控件,它可以对表格中的数据修改和删除,还可以按照不同的字段进行自定义的排序,它与DataTable的结合在小型系统的应用上简直帅呆了。
DataTable表
[置顶] 个人机房重构——DataTable与泛型的应用_第2张图片

DataGridView表
[置顶] 个人机房重构——DataTable与泛型的应用_第3张图片

我们看一下U层的代码:
            dgvLine.DataSource = dtcard                       '将dtcard的值传给DataGridView控件

            dgvLine.Columns(0).HeaderText = "卡号"            '显示表头
            dgvLine.Columns(1).HeaderText = "充值金额"
            dgvLine.Columns(2).HeaderText = "充值日期"
            dgvLine.Columns(3).HeaderText = "充值时间"
            dgvLine.Columns(4).HeaderText = "充值教师"
    

直接绑定DataGridView的数据源为DataTable就可以了,当然,需要的数据要在D层查询的时候加以限定,不要将不需要的数据也查出来。

DataGridView与泛型的结合

           DataGridView.Rows.Add(MyList.Count)    '数据表添加行,行数等于数据行数  
                For i = 0 To QueryDate.Count - 1
                    '变量写入行上的每个数据,rows代表行,Cell代表第几个格  
                    DataGridView.Rows(i).Cells(0).Value() = MyList(i).CardNo
                    DataGridView.Rows(i).Cells(1).Value() = MyList(i).RechargeCash
                    DataGridView.Rows(i).Cells(2).Value() = Format(MyList(i).RechargeDate)
                    DataGridView.Rows(i).Cells(3).Value() = MyList(i).RechargeTime
                    DataGridView.Rows(i).Cells(4).Value() = MyList(i).UserID
                    DataGridView.Rows(i).Cells(5).Value() = MyList(i).IsCheck
                Next

这两种方法各有优劣,就看大家喜欢哪种了。

扩展延伸(DataGridView控件)

DataGridView控件的使用方法请参考这篇博客,写的非常详细。(点这里)


总结:DataTable和泛型的使用大大的方便了我们的数据处理,综合考虑两者的优劣,根据实际需要两者结合使用,会起到事半功倍的作用。个人机房重构的完成不是目的,而是要在完成的过程中不断学习新知识,接触新的技术。运用并结合实践总结才是真正的目的。



你可能感兴趣的:([置顶] 个人机房重构——DataTable与泛型的应用)