背景
做机房收费系统的时候,遇到这样一个问题,将数据库表中的数据取出一行,将每个单元格中的内容填充到窗体
的文本框中。考虑到用DataReader获取结果的复杂性,我就用了泛型集合。可是这么一用却出现了如图所示的问
题。
问题一: 出现这种问题,是因为在DataTable转实体类型时表的字段类型和实体的字段类型不一致造成的。 这个也可以 这么说,中国人的孩子都随父姓,这是传统。但孩子随母姓,就有些不妥。
问题二:
数据库表中字段名和要转换的实体属性字段名不一致,导致转换后实体中depart为空值。
转换原理
分析:出现这些问题原因是我不太懂DataTable转实体类型的原理。经过查资料,加上自己的理解,终于将这种
转化方法掌握了,在敲代码时省了不少的功夫。 先看转换过程原理图。
原理:数据库表中每行数据都先转化成一个实体类,然后将转化好的实体类放入泛型集合中
泛型集合应用
实现功能:
将数据库表中数据分别加载到对应窗体文本框中
代码实现
(1)在实体层建一个实体转换过程
'***************************************************
'说明:泛型集合,完成datatable类型转换为实体类
'作者:王聚
'创建日期:2014-04-24 11:08:02
'版本号:V1.00
'***************************************************
Imports System.Collections.Generic
Imports System.Reflection
Public Class EntityMoudule
'将datatable转换为泛型集合
Public Shared Function converToList(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 '定义行集
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
'遍历该对象的所有属性
For Each pr In propertys
TmpName = pr.Name '将属性名称赋值给全局变量
'检查datatable是否包含此列,列名==对象的属性名
If (dt.Columns.Contains(TmpName)) Then '将此属性与datatable的列名比较,查看datatable是否包含此属性
'判断此属性是否有setter类
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) '将myT对象添加到集合
Next
Return mylist '返回实体集合
End Function
End Class
(2)在D层中实现代码
Public Class BasicDataBLL
Public Function BasicDataList() As IList(Of Entity.BasicDataEntity)
Dim Ibasicdata As IDAL.IBasicData
Dim factory As New Factory.BasicDataFac
Ibasicdata = factory.CreateIbasicdata()
Dim mylist As IList(Of Entity.BasicDataEntity)
mylist = Ibasicdata.SetDataList()
Return mylist
End Function
End Class
(3)接口层,定义一个接口
Public Interface IBasicData
Function SetDataList() As IList(Of Entity.BasicDataEntity)
End Interface
(4)工厂层,创建一个接口
Public Class BasicDataFac
Dim AssemblyName As String = "DAL"
Dim db As String = ConfigurationSettings.AppSettings("DB")
Function CreateIbasicdata() As IBasicData
Dim Ibasicdata As IBasicData
Ibasicdata = CType(Assembly.Load(AssemblyName).CreateInstance(AssemblyName + "." + db + "BasicDataDAL"),IBasicData)
Return Ibasicdata
End Function
End Class
(5)在B层中访问D层接口方法
Public Class BasicDataBLL
Public Function BasicDataList() As IList(Of Entity.BasicDataEntity)
Dim Ibasicdata As IDAL.IBasicData
Dim factory As New Factory.BasicDataFac
Ibasicdata = factory.CreateIbasicdata()
Dim mylist As IList(Of Entity.BasicDataEntity)
mylist = Ibasicdata.SetDataList()
Return mylist
End Function
End Class
(6)外观层,接收B层中的泛型集合
Public Class BasicDataFacade
Public Function BasicDatalist() As IList(Of Entity.BasicDataEntity)
Dim mylist As IList(Of Entity.BasicDataEntity)
Dim setdata As New BLL.BasicDataBLL
mylist = setdata.BasicDataList()
Return mylist
End Function
End Class
(7)U层,将泛型集合中数据填充到窗体中
Private Sub frmSetBasic_Load(sender As Object,e As EventArgs) Handles MyBase.Load
cmdCommit.Enabled = False '使确定按钮不能用
GroupBox1.Enabled = False '数据不可修改
cmdCancle.Enabled = False '取消不可用
'Dim mylist As IList(Of Entity.BasicDataEntity)
Dim loaddata As New Facade.BasicDataFacade
mylist = loaddata.BasicDatalist()
Dim num As Integer
num = mylist.Count - 1 'num表示表中最后一行
txtFixed.Text = mylist(num).FixedUser
txtCasual.Text = mylist(num).CasualUser
txtIncrease.Text = mylist(num).IncrementOfTime
txtAtLeast.Text = mylist(num).AtLeastTime
txtPrepare.Text = mylist(num).PrepareTime
txtLeast.Text = mylist(num).MinCharge
End Sub
(8)实体类型属性
Public Class BasicDataEntity
'一般用户属性
Private _userId As String
Public Property UserId As String
Get
Return _userId
End Get
Set(value As String)
_userId = value
End Set
End Property
'最少金额属性
Private _minCharge As Decimal
Public Property MinCharge As Decimal
Get
Return _minCharge
End Get
Set(value As Decimal)
_minCharge = value
End Set
End Property
'准备时间属性
Private _prepareTime As Integer
Public Property PrepareTime As Integer
Get
Return _prepareTime
End Get
Set(value As Integer)
_prepareTime = value
End Set
End Property
'最少上机时间属性
Private _atleastTime As Integer
Public Property AtLeastTime As Integer
Get
Return _atleastTime
End Get
Set(value As Integer)
_atleastTime = value
End Set
End Property
'单位递增时间属性
Private _incrementOfTime As Integer
Public Property IncrementOfTime As Integer
Get
Return _incrementOfTime
End Get
Set(value As Integer)
_incrementOfTime = value
End Set
End Property
'固定用户属性
Private _fixedUser As Decimal
Public Property FixedUser As Decimal
Get
Return _fixedUser
End Get
Set(value As Decimal)
_fixedUser = value
End Set
End Property
'临时用户属性
Private _casualUser As Decimal
Public Property CasualUser As Decimal
Get
Return _casualUser
End Get
Set(value As Decimal)
_casualUser = value
End Set
End Property
End Class
总结
泛型转化相对于DataReader处理数据简单化了,对数据的可操作性强,即在D层进行转化后,不管到那个层都
可以读取数据,优化代码结构,使业务逻辑简单化。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|