DataTable与泛型

来源:互联网 发布:库里2016总决赛数据 编辑:程序博客网 时间:2024/05/16 09:33
    刚刚开始机房重构的时候用的最多的就是DataTable,在用的时候感觉有一点点别扭,因为D层从数据库中
 把数据取出来之后直接通过DataTable返回到B层和U层了,这样对于数据库数据的安全性不太好。然后慢慢知
 道了泛型,通过泛型可以很好的解决数据安全的问题
 一、DataTable
  Public Function QueryCard(card As Entity.CardEntity) As Entity.CardEntity Implements ICard.QueryCard        Dim helper As New SqlHelper()    '实例化SqlHelper的对象为helper        Dim dt As DataTable              '接收从SqlHelper中返回的DataTable        Dim CardInfo As Entity.CardEntity = New Entity.CardEntity()        Dim Query As String = "select * from card_info where cardno=@cardno"    '存储Sql字段<span style="white-space:pre"></span><pre name="code" class="csharp">        '实例化SqlParameter,并传入参数
Dim sqlParams As SqlParameter() = {New SqlParameter("@cardno", card.CardNo)}  
                dt = helper.ExecSelect(Query, sqlParams)        '调用对象helper的方法        '把DataTable中的数据分别放入实体CardInfo中对应的字段        Try            CardInfo.CardNo = dt.Rows(0)(0)            CardInfo.Dates = dt.Rows(0)(5)            CardInfo.Time = dt.Rows(0)(6)            CardInfo.Status = dt.Rows(0)(7)            CardInfo.IsCheck = dt.Rows(0)(8)            CardInfo.Explain = dt.Rows(0)(9)            CardInfo.CardType = dt.Rows(0)(1)            CardInfo.Cash = dt.Rows(0)(2)            CardInfo.StudentNo = dt.Rows(0)(3)        Catch ex As Exception            '出错以后的提示            MsgBox("卡号不存在或错误", CType(vbOKOnly + MsgBoxStyle.Exclamation, MsgBoxStyle), "提示")        End Try        Return CardInfo    '返回实体    End Function
      这是把DataTable中的数据在D层中直接赋值给实体了,个人认为这样做会相对好一点,因为从数据库
  取得的数据不会直接返回给U层和B层;当然也可以在D层直接将获得的DataTable返回给U层B层,然后在U层
  对DataTable中的数据进行操作,很明显这样对数据来说是很不安全的,而且三层之间通过DataTable传输
  数据也会增加三层的耦合度
 二、泛型
    'DataTable转换为泛型    Public Shared Function ConvertList(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                             '定义DataTable的行集        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                    'PropertyInfo的实例化            '遍历pr对象在集合中的所有属性            For Each pr In Propertys                TmpName = pr.Name                     '属性名称赋值给定义的临时变量                '检查DataTable中是否包含此属性,如果包含继续执行                If (dt.Columns.Contains(TmpName)) Then                    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)         '把获得的属性添加到集合中        Next        Return MyList               '返回集合    End Function
    D层直接调用该方法即可
    Public Function SelectStudent(ByVal student As Entity.StudentEntity) As IList(Of Entity.StudentEntity) Implements ISelectStudent.SelectStudent        Dim helper As New SqlHelper        Dim dt As DataTable        Dim sql As String = "select * from student_info where studentno=@studentno"        Dim stuInfo As List(Of Entity.StudentEntity)<span style="white-space:pre"></span>        Dim para As SqlParameter() = {New SqlParameter("@studentno", student.StudentNo)}
<span style="white-space:pre"></span>'调用SqlHelper方法        dt = helper.ExecSelect(sql, para)<span style="white-space:pre"></span>'DataTable类型转换为泛型        stuInfo = Entity.Genericity.ConvertList(Of Entity.StudentEntity)(dt)        Return stuInfo    End Function

     这样通过泛型的转换可以让B层和D层之间解耦,泛型定义的类型限制也可以在很大程度上保证数据的安
  全性。
 三、小结
     在使用泛型的时候一定要注意数据类型,实体中的数据类型与数据库的数据类型一定要保持一直
     在多用一些自己没用的技术,对自己很有帮助的。。
1 0