在个人版机房收费系统中,总是会遇到各种问题。记得完成登录的时候师傅就和我说过:数据传递最好不要用DataTable,开始并不是很理解,感觉DataTable传递数据还是挺方便的。所以在在查询中,需要有返回值的,返回的就是DataTable类型,那么问题就来了。
【知识点】
DataTable是一个临时保存数据的网格虚拟表,将数据存放在表中,一层一层的传递到U层。但是它的缺点是与数据库的耦合性太强了,使用DataTable要填写数据库中的字段,很容易出错,编译者必须清楚的了解数据库,带来很多麻烦,不利于合作开发。代码如下:
<span style="font-size:18px;">Dim table As DataTable '声明一个DataTable类型变量
table = sqlHelper.ExecSelect(Sql, CommandType.Text, sqlParams)
Dim aUser As New Entity.LoginEntity '实例化过程
If table.Rows.Count <> 0 Then
'表中内容不为空,执行
aUser.userID = table.Rows(0).Item("userID").ToString()
aUser.passWord = table.Rows(0).Item("passWord").ToString()
aUser.level = table.Rows(0).Item("level").ToString()
aUser.userName = table.Rows(0).Item("userName").ToString()
aUser.head = table.Rows(0).Item("head").ToString()
Return aUser
Else
'返回一个空的实体
Return New LoginEntity
End If</span>
为了避开DataTable的弊端,就是将其转换成泛型。泛型集合本质就是在编译阶段就告诉编译器,数据结构中元素的种类,既然编译器知道了元素的种类,自然就避免了拆箱、封箱的操作,提高的程序的性能。编译者不用了解数据库的内部构成,直接点一下就会出来相应字段,避免了很多错误的出现。将DataTable转换成泛型的方法抽象出来,写成一个类似于SQLHelper的类,可以放在D层,直接调用。
<span style="font-size:18px;">'/*************************************************************************************
'类 名 称: ConvertHelper
'命名空间:DAL
'创建时间:2015/2/24
'作 者:王文茹
'小 组:
'修改时间:
'修 改 人:
'版 本 号:v1.0.0
'*************************************************************************************/
Imports System.Collections.Generic '增加泛型的命名空间
Imports System.Reflection '引入反射
Public Class ConvertHelper
'将datatable转化为泛型集合
Public Shared Function convertToList(Of Turn As {New})(ByVal table 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 table.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 (table.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</span>
【小结】
在做机房的过程中总是会遇到各种各样的问题,虽然现在还没有都跨过去,但是方法总比问题多铭记在心中,总是会跨过去的。