對於機房收費系統的重構。從大的方面來看。無非就是對於數據庫的四個操作。增刪改查。而且我們用的是三層架構進行重構。D層用來和數據庫打交道。進行這四個操作就須要有返回值,增刪改在這里不多說。可是當進行查的時候。d層須要數據給b層,那么我們以什么樣的形式返回最好呢?
剛開始接觸三層的時候,我返回的是datatable,就是dt.Rows[0][“xxx”]的形式,感覺實現了。就非常厲害了,后來通過與大家交流發現,事實上另一種更好用的方法。就是利用實體類填充泛型集合。
那么問題就出來了:
1.泛型集合是什么?
2.為什么說用它會更好?
一、是什么?
泛型,顧名思義就是泛泛的類型. 也就是沒有確定的類型. 那么沒有確定類型怎么使用呢?實際上。使用的時候規定類型即可了.
集合,就是一種處理多個數據類型的類。而且一般你會在多個應用程序中使用同一個集合的多種不同的形式。你不須要每次依據草稿建立集合,而是使用泛型建立一個泛型類原型(prototype)。
在使用的時候,依據須要處理的數據類型。將List<T>尖括號里的T換成相應的類型,並創建相應的實例就能夠使用了.
二、為什么?
首先。你須要給代碼加入例如以下所看到的的Imports語句:
| Imports System.Collections.Generic |
加入Imports語句之后。你就能夠建立泛型類了。主要的類看起來非經常見。你能夠使用屬性、函數、子程序、字段或能夠在類中使用的其他不論什么東西。
Public Class ConvertHelperEntity
Public Shared Function convertToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)
'將datatable 轉換成泛型集合
Dim myList As New List(Of T) '定義終於返回的集合
Dim myType As Type = GetType(T) '得到實體類的類型名
Dim dr As DataRow '定義行集
Dim tempName 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
tempName = pr.Name '將屬性名稱賦給暫時變量
'檢查datatable 是否包括此列(列名==對象的屬性名)
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(myT, value, Nothing) '在執行期間。通過反射,動態的訪問一個對象的屬性
End If
End If
Next
myList.Add(myT) '加入到集合
Next
Return myList '返回實體集合
End Function
End Class
我們須要在實體層,加入一個實體類,
由於創建集合的基礎是要有類,然后才干將對象放入集合中。
那么我們為什么要說它比datatable要好呢?用泛型集合,我們在D層把DataTable轉換成單個實體類,再把實體類填充到泛型集合中。
其核心思想圖:

將其優缺點進行對照可得:
| Datatable |
List<T> |
| 很easy寫錯,編譯器不檢查 |
按一下點,自己出來。不會寫錯 |
| 必須了解數據庫的結構 |
不必了解數據庫結構 |
| 不符合面向對象思想 |
符合面向對象思想 |
| DataTable為弱類型。無法直觀的看出字段的數據類型。 |
實體類的屬性是強類型,每一個字段的類型都是已知的。 |
