前言:
接着上一篇继续来说七层各个层之间的调用关系,以及代码是如何运用的。刚刚一直再说实体,那下面就来说一下Datatable和泛型是如何转换的。
内容:
(3)Datatable转泛型
下面我们引入一个图,这样更容易理解:
Datatable是断开式的数据集合,所以一旦从数据库获取,就会在内存中创建一个数据的副本,以便使用。而Datatable中每一个字段都是与实体的属性对应着的,一个字段对应实体中的一个属性。Datatable中的每一行数据对应一个实体,转为泛型后放入IList集合中。
代码:
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) 'IList表示可按照索引单独访问的对象的非泛型集合。
'convertToList(Of Turn As {New}) 这里的new是用来约束T的
Dim myList As New List(Of Turn) '定义最终返回的集合
Dim myType 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
If (Pr.CanWrite = False) Then
Continue For '将执行过程立即转移到for循环的下一个迭代过程
End If
Dim value As Object = dr(tempName) '定义一个对象型的变量来保存列的值
If (value IsNot DBNull.Value) Then '如果非空,则赋给对象的属性
Pr.SetValue(myTurn, value, Nothing) '在运行期间,通过反射,动态的设置一个对象的属性
End If
End If
Next
myList.Add(myTurn) '添加到集合
Next
Return myList '返回实体集合
End Function
End Class
思考:为什么要放在DAL层转换呢?放在别的层可以不?
5、IDAL层(接口)
(1)登录接口
Imports System.Reflection
Imports Entity.Entity
Public Interface LoginIDAL
'定义查找用户的方法,用于数据库中查找用户
Function selectUser(ByVal UserInfo As Entity.Entity) As List(Of Entity.Entity)
'更改用户登录状态
Function UpdataUserStatus(ByVal UserInfo As Entity.Entity) As Boolean
End Interface
(2)工作记录接口
Imports System.Reflection
Imports Entity.Entity
Public Interface IWorkLog
'插入工作记录
Function InsertWorkLog(ByVal worklog As Entity.WorkLogEntity)
End Interface
6、Factory层
(1)登录工厂
Imports System.Configuration '添加对配置文件的引用
Imports System.Reflection '引用反射
Imports IDAL
Imports System.Data
Public Class LoginFactory
Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称、命名空间(DAL)
Dim db As String = System.Configuration.ConfigurationSettings.AppSettings("DB") '配置文件中的名称
Public Function CheckUserInfo() As IDAL.LoginIDAL
'CheckUserInfo() --新建实例名
'IDAL.LoginIDAL --IDAL.需要实例化的类名
'className需要反射的类型全名(包括命名空间的全路径)
Dim className As String = db + "." + "LoginDAL" '声明要实例化的D层类的名称
' Dim classname As String = AssemblyName + "." + db + "DAL"
'将实例化的D层类通过向上转型转换成接口类,然后通过调用接口类中的函数来调用D层中实现该接口的函数。
Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IDAL.LoginIDAL)
'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果
End Function
End Class
(2)工作记录工厂
这个跟上面的登录工厂基本一样。
Imports System.Reflection
Imports IDAL
Imports System.Configuration
Public Class WorkLogFactory
Private Shared ReadOnly AssemblyName As String = "DAL" '数据程序集名称、命名空间(DAL)
Dim db As String = System.Configuration.ConfigurationSettings.AppSettings("DB") '配置文件中的名称
Public Function CheckWorkLog() As IDAL.IWorkLog
'CheckWorkLog() --新建实例名
'IDAL.LoginIDAL --IDAL.需要实例化的类名
'className需要反射的类型全名(包括命名空间的全路径)
Dim className As String = db + "." + "WorkLogDAL" '声明要实例化的D层类的名称
'将实例化的D层类通过向上转型转换成接口类,然后通过调用接口类中的函数来调用D层中实现该接口的函数。
Return CType(Assembly.Load(AssemblyName).CreateInstance(className), IDAL.IWorkLog)
'CType函数将返回表达式显示地转换为指定的数据类型、对象、结构、类或接口后的结果
End Function
End Class