机房重构——透过实践看Datatable和泛型

时间:2021-05-30 04:50:12

Datatable定义

     是一个临时保存数据的网格虚拟表,其他使用datatable的对象包括datasetdataview。(摘自百度百科)我理解的datatable就是一张表,而dataset当于一个数据库,他可以包括一张表也可以包括很多张表。

泛型定义

    1.在程序编码中一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是当今较常见的定义)

    2.在程 序编码中一些包含参数的类。其参数可以代表类或对象等等。(人们大多把这称作模板)不论使用哪个定义,泛型的参数在真正使用泛型时都必须作出指明。

何时用

     说到datatable类型的返回值就需要和sqlhelper结合起来,因为datatable返回的是一张表,所以在需要用表中的数据的时候就可以使用datatable型,在D层的返回值定义成datatable类型,那我想使用表中的数据,我就不可以用泛型了吗?我的理解是“不是”!既然他们都可以在想用表中数据的时候使用,那他们区别再哪里呢?

区别与好处

      在想要提高效率的前提下,我的理解是当你需要表中的部分字段时最好使用datatable,因为这样的查询速度很快。用过泛型的伙伴们都知道在需要表中数据的前提下,还想用泛型,这时候就需要用converthelper来将datatable转泛型,不妨可以在D层将datatable转泛型的地方设置一个断点,亲身体会一下,他会将表中所有的字段都进行转换,这样是很浪费时间的。在想要保证数据安全的前提下,在敲机房的时候用泛型的时候经常在Time字段转泛型的时候出现类型错误,这种情况就是数据库中字段类型不合理造成的。泛型的好处就在于他不会自动强制转换数据的类型,如果数据类型在转泛型的时候不合理他会报错而不是自动强制转换,这样就可以保证数据的安全。所以这两种类型的使用还需要再具体情况下权衡利弊之后再决定使用哪种类型较好!

●应用

1.Datatable结合Datagridview控件

        在操作员的查询收取金额的功能中,需要将数据库表中的部分字段信息查询出后添加到Datagridview控件来显示。下边的例子只是展示了U层和D层的代码,体验一下如何将Datatable型的返回值赋值添加到DatagridView控件中,其余层不做展示,和和其功能并无区别。

1.1窗体展示

       机房重构——透过实践看Datatable和泛型


1.2U层代码展示

<span style="font-size:18px;"> Private Sub btnOk_Click(sender As Object, e As EventArgs) Handles btnOk.Click
Dim QueryCashEntity As New Entity.VRechargeEntity '查询收取金额实体
Dim QueryCashFacade As New Facade.QueryCashFacade '查询收取金额外观
Dim dt As DataTable
Dim Log As Integer '用来记录返回的记录数目
Try
DGV.Rows.Clear() '点击查询按钮的时候先将控件中数据清除
QueryCashEntity.dateStart = Format(DTPstart.Value, "yyyy-MM-dd") '起始时间
QueryCashEntity.dateEnd = Format(DTPend.Value, "yyyy-MM-dd") '终止时间
dt = QueryCashFacade.QueryCash(QueryCashEntity)
DGV.Rows.Add(dt.Rows.Count)
'将数据显示在控件中
For Log = 0 To dt.Rows.Count - 1
DGV.Rows(Log).Cells(0).Value() = dt.Rows(Log).Item(1) '卡号
DGV.Rows(Log).Cells(1).Value() = dt.Rows(Log).Item(6) '充值金额
DGV.Rows(Log).Cells(2).Value() = Format(dt.Rows(Log).Item(4), "yyyy-MM-dd") '充值日期
DGV.Rows(Log).Cells(3).Value() = dt.Rows(Log).Item(5) '充值时间
DGV.Rows(Log).Cells(4).Value() = dt.Rows(Log).Item(2) '充值教师
DGV.Rows(Log).Cells(5).Value() = dt.Rows(Log).Item(7) '结账状态

Next
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try

End Sub</span>

1.3D层代码展示

<span style="font-size:18px;">Imports DAL   '引用D层
Imports System.Data.SqlClient
Public Class QueryCashDAL : Implements IDAL.IQueryCash


Public Function QueryCash(QueryCashEntity As Entity.VRechargeEntity) As DataTable Implements IDAL.IQueryCash.QueryCash
Dim dt As New DataTable
'Dim dt As DataTable
Dim SqlHelper As New SqlHelper '定义一个sqlheler
Dim Parameter As SqlParameter()
'给变量赋值
Parameter = {New SqlParameter("@dateStart", QueryCashEntity.dateStart), New SqlParameter("@dateEnd", QueryCashEntity.dateEnd)}
'查询语句
Dim strText As String = "select * from T_RechargeInfo where date between @dateStart and @dateEnd"
dt = SqlHelper.ExecSelect(strText, CommandType.Text, Parameter) '查询数据
'返回Datatable
Return dt
End Function
End Class
</span>

2.泛型结合Datatable控件

2.1上下机记录查询窗体展示

  机房重构——透过实践看Datatable和泛型

2.2 U层代码展示

<span style="font-size:18px;">Private Sub btnQuery_Click(sender As Object, e As EventArgs) Handles btnQuery.Click
Dim OnlineLogEntity As New Entity.VQueryOnlineLogEntity '查询上机记录实体
Dim OnlineLogFacade As New Facade.QueryOnlineLogFacade '查询上机记录外观层实体
Dim myList As List(Of Entity.VQueryOnlineLogEntity) '泛型
Dim OnlineLogCount As Integer
Try
DGV1.Rows.Clear() '先将控件中数据清空
If txtCardNo.Text.Trim() <> "" Then
OnlineLogEntity.studentCardNo = txtCardNo.Text
Else
MsgBox("卡号不能为空")
End If
myList = OnlineLogFacade.SelectOnlineLog(OnlineLogEntity) '传到外观层
DGV1.Rows.Add(myList.Count)
DGV1.AllowUserToAddRows = False '最后不添加空行
'将数据显示在控件中
For OnlineLogCount = 0 To myList.Count - 1
DGV1.Rows(OnlineLogCount).Cells(0).Value() = myList(OnlineLogCount).studentCardNo
DGV1.Rows(OnlineLogCount).Cells(1).Value() = myList(OnlineLogCount).studentName
DGV1.Rows(OnlineLogCount).Cells(2).Value() = Format(myList(OnlineLogCount).onDate, "yyyy-MM-dd")
DGV1.Rows(OnlineLogCount).Cells(3).Value() = myList(OnlineLogCount).onTime
DGV1.Rows(OnlineLogCount).Cells(4).Value() = Format(myList(OnlineLogCount).offDate, "yyyy-MM-dd")
DGV1.Rows(OnlineLogCount).Cells(5).Value() = myList(OnlineLogCount).offTime
DGV1.Rows(OnlineLogCount).Cells(6).Value() = myList(OnlineLogCount).consumeMoney
DGV1.Rows(OnlineLogCount).Cells(7).Value() = myList(OnlineLogCount).balance
Next
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try</span>

2.3 D层代码展示

<span style="font-size:18px;">Imports Entity
Imports System.Data.SqlClient
Imports IDAL
Public Class QueryOnlineLogDAL : Implements IDAL.IOnlineLog


Public Function SelectOnlineLog(OnlineLogEntity As Entity.VQueryOnlineLogEntity) As List(Of Entity.VQueryOnlineLogEntity) Implements IDAL.IOnlineLog.SelectOnlineLog
Dim dt As New DataTable
Dim myList As List(Of Entity.VQueryOnlineLogEntity) '泛型
Dim Parameter As SqlParameter()
'赋值
Parameter = {New SqlParameter("@studentCardNo", OnlineLogEntity.studentCardNo)}
'查询语句
Dim strText As String = "select * from V_QueryOnlineLog where studentCardNo=@studentCardNo"
Dim SqlHelper As New SqlHelper '定义一个SqlHelper类型
'返回datatable类型
dt = SqlHelper.ExecSelect(strText, CommandType.Text, Parameter)
'转泛型
myList = ConvertHelper.ConvertTolist(Of Entity.VQueryOnlineLogEntity)(dt)
Return myList
End Function
End Class
</span>

总结

      这两种类型都可以将数据库中的数据取出来,在效率和安全方面各有优缺点,具体情况还需要在这两方面权衡之下考虑用哪一种。没有最好,只有最合适。亲身体验是最好的老师!