做机房收费系统的时候,遇到这样一个问题,将数据库表中的数据取出一行,将每个单元格中的内容填充到窗体
的文本框中。考虑到用DataReader获取结果的复杂性,我就用了泛型集合。可是这么一用却出现了如图所示的问
题。
出现这种问题,是因为在DataTable转实体类型时表的字段类型和实体的字段类型不一致造成的。 这个也可以
这么说,中国人的孩子都随父姓,这是传统。但孩子随母姓,就有些不妥。
分析:出现这些问题原因是我不太懂DataTable转实体类型的原理。经过查资料,加上自己的理解,终于将这种
转化方法掌握了,在敲代码时省了不少的功夫。 先看转换过程原理图。
原理:数据库表中每行数据都先转化成一个实体类,然后将转化好的实体类放入泛型集合中
'*************************************************** '说明:泛型集合,完成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
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
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
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
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
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
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层进行转化后,不管到那个层都
可以读取数据,优化代码结构,使业务逻辑简单化。
原文地址:http://blog.csdn.net/wangju2013/article/details/45624363