首先要明白dataset的作用:DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据库,DataSet是不依赖于数据库的独立数据集合。就是当数据库关闭的时候,DataSet依然是可用的。它就相当于一个仓库,把数据放到这个仓库中,也就是内存中,然后下次读取数据的时候就可以直接从内存中获得。
它的好处是访问速率快,使用方便。坏处便是占用内存,在三层架构中,因为从DataSet中读取数据的时候用的都是表中的真实字段,所以在表示层和业务逻辑层中完全暴露了数据的结构,这样就不符合面向对象的原则。
所以可以用泛型集合来代替dataset存储数据,把数据封装到实体中。比如想要获得用户的用户名,则可以直接写mylist.Item(0).UserName,而不用像dataset一样访问数据表datatable.rows(1).Item(2)。这样就很好把数据封装到泛型里了。泛型符合面向对象的思想 。泛型集合中将每一条数据当成了一个实体来对待,而每个字段则当成该实体的不同的属性。
下面是把datatable数据表datatable转换成泛型集合的代码:
Imports System.Collections.Generic
Imports System.Reflection
Public Class ConvertHelper
'of T as new 用来对T进行约束,必须包含有空的无参构造函数
Public Shared Function ConvertToList(Of T As {New})(ByVal dt As DataTable) As List(Of T)
'定义一个泛型集合,用于存放返回集合
Dim ds As New List(Of T)
'定义一个变量,来得到返回集合中实体类型
Dim type As Type = GetType(T)
'定义一个临时变量,用来存放datatable中的每个实体的属性
Dim proName As String = String.Empty '初始调用时,为空字符串
'定义行实体
Dim dr As DataRow
'遍历DataTable中的所有数据行,即所有记录
For Each dr In dt.Rows
'实例化一个泛型集合中的实体,即代表一条记录
Dim record As New T
'定义一个属性信息的集合
'propertyInfo探索屬性 (Property) 的屬性 (Attribute),並提供屬性中繼資料 (Metadata) 的存取
Dim propertys() As PropertyInfo = record.GetType().GetProperties() '获取实体的所有属性
'遍历所有属性
Dim pro As PropertyInfo
For Each pro In propertys
'每循环一次将属性的名称赋值给临时变量proName
proName = pro.Name
'利用临时遍历中的属性名称来检查该记录中是否包含此列
If dt.Columns.Contains(proName) Then
'包含此列的同时,必须保证该列可写
If pro.CanWrite = False Then Continue For '直接跳出,继续执行循环
'取值
Dim value As Object = dr(proName) '保存列名的值
If (value.ToString <> DBNull.Value.ToString()) Then '如果非空,则赋给对象的属性
'用索引化属性的可选索引值设置指定对象的该属性值
pro.SetValue(record, value, Nothing) '在运行期间,通过反射,动态的访问一个对象的属性
End If
End If
Next
ds.Add(record)
Next
Return ds '返回实体的泛型集合
End Function
End Class