背景:很早就听说了DataTable不如泛型好,但是在机房重构的时候我还是使用了它,因为一件衣服不试穿一下肯定不知道它到底好不好,所以在重构的时候泛型也用了,DataTable也用了,现在说一说他们到底是什么?又有什么区别呢?
DataTable表示临时保存数据的网格虚拟表,它完全是在内存中的一个独立存在,包含了这张表的全部信息。DataTable可以是从通过连接从数据库中读取出来形成的一个表,一旦将内容读到DataTable中,此DataTable就可以跟数据源断开而独立存在;也可以是完全由程序自己通过代码来建立的一个表。
在重构的时候在u层里调用的时候用到了DataTable,下面是具体用到的方法
<span style="font-size:14px;">Dim dt As New DataTable '获取基本数据 dt = resigercardfacade.ISMoney(basicdata) fixedUnit = dt.Rows(0).Item("Nmc_Rate") temUnit = dt.Rows(0).Item("Nmc_TmpRate") preparedtime = dt.Rows(0).Item("Int_PrepareTime") UnitTime = dt.Rows(0).Item("Int_UnitTime") limitedtime = dt.Rows(0).Item("Int_leastTime")</span>
同时还有另外一种的使用方法dt.Rows(0).Item(0)因为这个太麻烦了,因为还要找到想要找到数据的顺序,所以就没有用
缺点:
1、非常容易写错,而且编译器不检查。
2、必须了解数据库的结构。
3、不符合面向对象编程思想。
4、DataTable为弱类型,无法直观的看出字段的数据类型。
泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。
具体如何应用:
<span style="font-size:14px;"> Dim mylist1 As New List(Of Entity.OnLineRecordEntity) mylist1 = onLineRecordfacade.offIsCardNo(OnlineRecordEntity) OnlineRecordEntity.Ontime = mylist1(0).Ontime </span>
优点:
1、编写B层的人员无需手动填写需要的字段,直接按一下点,全都提示出来了,想用哪个用哪个,不会出现写错的情况。
2、不必了解数据库结构。
3、符合面向对象思想。
4、实体类的属性是强类型,每个字段的类型都是已知的
实体类即数据库的反应,因此实体类中的属性和数据库表中的字段是相对应的。把DataTable中的每一行记录视为一个实体类,把其中的字段读取出来,存放到实体类的属性中,再把所有的实体类存在泛型集合中。因此,DataTable中有多少个记录,泛型集合中就有多少个实体类,每个实体类的属性和DataTable的字段是相对应的。
<span style="font-size:14px;">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) '这里的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 '将此属性与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>
<span style="font-size:14px;"> '判断是否有此卡号 Public Function SelectCard(cardEntity As Entity.CardEntity) As List(Of Entity.CardEntity) Implements IDAL.ICardInfo.SelectCard Dim sql As New SqlHelper.SqlHelper Dim dt As New DataTable Dim mylist As New List(Of Entity.CardEntity) Dim sqlparams As SqlParameter() = {New SqlParameter("@CardNo", cardEntity.Chr_Cardno)} Dim strsql As String = "select * from T_card where Chr_Cardno=@CardNo" dt = sql.ExecSelect(strsql, CommandType.Text, sqlparams) mylist = ConvertHelper.convertToList(Of Entity.CardEntity)(dt) Return mylist End Function</span>
这个就是在写实体类的时候,写的是string型的,但是数据库是Decimal型的,只要把实体类中的属性给成Decimal型的问题就解决了。
小结:不管怎么样都要去尝试,不要别人都说不要就不要用,要知道为什么不去用,鞋合不合适自己试穿了才知道。所以以后学习的过程中要多加探索。