通常情況下,我們在做工程項目的時候,需要把待處理的數據存儲在數據庫中。
通過 SQL
的 Select
語句很容易把查詢的結果以 DataTable
的方式得到,但在對 DateTable
中的數據進行進一步的檢索時遠遠沒有模型類 List<T>
方便。 所以,在做工程項目時,會把查詢到的 DataTable
轉化成模型類 List<T>
, 處理完畢後如果有所改動則把這個模型類 換回成 DataTable
以便完成數據庫中的相應改動。
上週在做一個電力局項目時對導入的上萬條數據進行插入操作就是這樣做的,參見一下圖文:
技術分析
如何實現 DataTable
與 List<T>
的相互轉化呢?
這裏需要掌握 C# 中的 泛型 以及 反射 的基礎知識。
泛型部分:
- 泛型(一):泛型概述
- 泛型(二):泛型的優點
- 泛型(三):泛型之類型參數
- 泛型(四):泛型之類型參數約束
- 泛型(五):泛型類
- 泛型(六):泛型接口
- 泛型(七):泛型方法
- 泛型(八):泛型委託
- 泛型(九):泛型代碼中的default關鍵字
反射部分:
- 反射技術(一):前期準備
- 反射技術(二):窺視內部
- 反射技術(三):深入窺視字段
- 反射技術(四):深入窺視屬性
- 反射技術(五):深入窺視方法
- 反射技術(六):深入窺視DLL內部
- 反射技術(七):通過反射實例化對象
通過泛型,我們可以把任何一個模型類 List<T>
轉化成 DataTable
,也可以把任何一個 DataTable
轉化成對應的 List<T>
,只要這裏 T
類型的 public 屬性 與 DataTable
的 ColumnName
對應即可。當然屬性的獲取是通過反射技術完成的。
有關泛型和反射的知識,可以查看上面的圖文,我在這裏就不在重複了。
代碼實現
下面,通過一個實際項目的例子來說明相互轉換的代碼與具體的應用。
Step1. 設備臺賬的結構 AcountItem
。
/// <summary>
/// 臺賬Item
/// </summary>
public class AccountItem
{
/// <summary>
/// 設備ID
/// </summary>
public string EquipmentId
{
get;
set;
}
/// <summary>
/// 廠站名稱
/// </summary>
public string FactoryStationName
{
get;
set;
}
/// <summary>
/// 廠站類型
/// </summary>
public string FactoryStationType
{
get;
set;
}
/// <summary>
/// 一次設備名稱
/// </summary>
public string PrimaryDeviceName
{ get; set; }
/// <summary>
/// 一次設備電壓等級
/// </summary>
public string PrimaryDeviceVoltageLevel
{ get; set; }
/// <summary>
/// 製造廠家
/// </summary>
public string Manufacturer
{
get;
set;
}
/// <summary>
/// 保護類別
/// </summary>
public string ProtectionCategory
{
get;
set;
}
/// <summary>
/// 保護型號
/// </summary>
public string ProtectionType
{
get;
set;
}
/// <summary>
/// 軟件版本
/// </summary>
public string SoftwareVersion
{
get;
set;
}
/// <summary>
/// 保護名稱
/// </summary>
public string ProtectionName
{
get;
set;
}
/// <summary>
/// 投運日期
/// </summary>
public string CommissionDate
{
get;
set;
}
/// <summary>
/// 出廠日期
/// </summary>
public string ProductionDate
{
get;
set;
}
/// <summary>
/// 所在屏櫃
/// </summary>
public string ScreenCabinets
{
get;
set;
}
/// <summary>
/// 保護套別
/// </summary>
public string ProtectiveSleeve
{
get;
set;
}
}
Step2. 把模型類 List<T>
轉化爲 DataTable
。
public static DataTable ListToDataTable<T>(IEnumerable<T> collection)
{
if (collection == null)
throw new ArgumentNullException();
PropertyInfo[] props = typeof (T).GetProperties();
DataTable dt = new DataTable();
dt.Columns.AddRange(props.Select(
p => new DataColumn(p.Name, p.PropertyType)
).ToArray());
if (collection.Any())
{
for (int i = 0; i < collection.Count(); i++)
{
ArrayList tempList = new ArrayList();
foreach (PropertyInfo pi in props)
{
object obj = pi.GetValue(collection.ElementAt(i), null);
tempList.Add(obj);
}
object[] array = tempList.ToArray();
dt.LoadDataRow(array, true);
}
}
return dt;
}
Step3. 舉例,把 List<AcountItem>
轉化爲 DataTable
。
// 初始化鏈表並加入數據。
List<AccountItem> lst = new List<AccountItem>();
DataTable dt = ListToDataTable(lst);
dt
數據表列集合的列名依次爲:
- EquipmentId
- FactoryStationName
- FactoryStationType
- PrimaryDeviceName
- PrimaryDeviceVoltageLevel
- Manufacturer
- ProtectionCategory
- ProtectionType
- SoftwareVersion
- ProtectionName
- CommissionDate
- ProductionDate
- ScreenCabinets
- ProtectiveSleeve;
Step4. DataTable 轉化爲 List。
public static List<T> DataTableToList<T>(DataTable dt) where T : new()
{
List<T> result = new List<T>();
foreach (DataRow dr in dt.Rows)
{
T item = new T();
PropertyInfo[] props = item.GetType().GetProperties();
foreach (PropertyInfo pi in props)
{
string tempName = pi.Name;
if (dt.Columns.Contains(tempName))
{
if (pi.CanWrite == false)
continue;
object value = dr[tempName];
if (value != DBNull.Value)
pi.SetValue(item, value, null);
}
}
result.Add(item);
}
return result;
}
Step5. 舉例,把 Step3 得到的 DataTable
轉化爲 List<AccountItem>
。
List<AccountItem> lst = DataTableToList(dt);
通過調用 Step4 帶約束的泛型方法,可以得到模型類 List<AccountItem>
。
總結
到此爲止,DataTable
與 List<T>
的相互轉換就介紹完了,由於整個項目都是利用 List<T>
來構建邏輯的,所以整個系統可以具有良好的結構,通過 LINQ 也能滿足效率的要求。今天就到這裏吧!See You!
相關圖文:
- 如何利用 C# 實現 K 最鄰近算法?
- 如何利用 C# 實現 K-D Tree 結構?
- 如何利用 C# + KDTree 實現 K 最鄰近算法?
- 如何利用 C# 對神經網絡模型進行抽象?
- 如何利用 C# 實現神經網絡的感知器模型?
- 如何利用 C# 實現 Delta 學習規則?
- 如何利用 C# 開發「桌面版百度翻譯」軟件!
- 如何利用 C# 開發「股票數據分析軟件」(上)
- 如何利用 C# 開發「股票數據分析軟件」(中)
- 如何利用 C# 開發「股票數據分析軟件」(下)
- 如何利用 C# 爬取「財報說」中的股票數據?
- 如何利用 C# 爬取 One 持有者返利數據!
- 如何利用 C# 爬取Gate.io交易所的公告!
- 如何利用 C# 爬取BigOne交易所的公告!
- 如何利用 C# 爬取 ONE 的交易數據?
- 如何利用 C# 爬取「京東 - 計算機與互聯網圖書銷量榜」!
- 如何利用 C# 爬取「噹噹 - 計算機與互聯網圖書銷量榜」!
- 如何利用 C# 爬取「互動出版網 - 計算機圖書銷量榜」!
- 如何利用 C# 爬取「中國圖書網 - 計算機與互聯網圖書銷量榜」!
- 如何利用 C# 爬取「貓眼電影:熱映口碑榜」及對應影片信息!
- 如何利用 C# 爬取「貓眼電影專業版:票房」數據!
- 如何利用 C# 爬取「貓眼電影:最受期待榜」及對應影片信息!
- 如何利用 C# 爬取「貓眼電影:國內票房榜」及對應影片信息!
- 如何利用 C# + Python 破解貓眼電影的反爬蟲機制?
- 如何利用 C# 爬取帶 Token 驗證的網站數據?