通常情況下荒勇,我們?cè)谧龉こ添?xiàng)目的時(shí)候柒莉,需要把待處理的數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫中。
通過 SQL
的 Select
語句很容易把查詢的結(jié)果以 DataTable
的方式得到沽翔,但在對(duì) DateTable
中的數(shù)據(jù)進(jìn)行進(jìn)一步的檢索時(shí)遠(yuǎn)遠(yuǎn)沒有模型類 List<T>
方便兢孝。 所以,在做工程項(xiàng)目時(shí)仅偎,會(huì)把查詢到的 DataTable
轉(zhuǎn)化成模型類 List<T>
跨蟹, 處理完畢后如果有所改動(dòng)則把這個(gè)模型類 換回成 DataTable
以便完成數(shù)據(jù)庫中的相應(yīng)改動(dòng)。
上周在做一個(gè)電力局項(xiàng)目時(shí)對(duì)導(dǎo)入的上萬條數(shù)據(jù)進(jìn)行插入操作就是這樣做的橘沥,參見一下圖文:
技術(shù)分析
如何實(shí)現(xiàn) DataTable
與 List<T>
的相互轉(zhuǎn)化呢?
這里需要掌握 C# 中的 泛型 以及 反射 的基礎(chǔ)知識(shí)座咆。
泛型部分:
- 泛型(一):泛型概述
- 泛型(二):泛型的優(yōu)點(diǎn)
- 泛型(三):泛型之類型參數(shù)
- 泛型(四):泛型之類型參數(shù)約束
- 泛型(五):泛型類
- 泛型(六):泛型接口
- 泛型(七):泛型方法
- 泛型(八):泛型委托
- 泛型(九):泛型代碼中的default關(guān)鍵字
反射部分:
- 反射技術(shù)(一):前期準(zhǔn)備
- 反射技術(shù)(二):窺視內(nèi)部
- 反射技術(shù)(三):深入窺視字段
- 反射技術(shù)(四):深入窺視屬性
- 反射技術(shù)(五):深入窺視方法
- 反射技術(shù)(六):深入窺視DLL內(nèi)部
- 反射技術(shù)(七):通過反射實(shí)例化對(duì)象
通過泛型痢艺,我們可以把任何一個(gè)模型類 List<T>
轉(zhuǎn)化成 DataTable
,也可以把任何一個(gè) DataTable
轉(zhuǎn)化成對(duì)應(yīng)的 List<T>
介陶,只要這里 T
類型的 public 屬性 與 DataTable
的 ColumnName
對(duì)應(yīng)即可堤舒。當(dāng)然屬性的獲取是通過反射技術(shù)完成的。
有關(guān)泛型和反射的知識(shí)哺呜,可以查看上面的圖文植酥,我在這里就不在重復(fù)了。
代碼實(shí)現(xiàn)
下面弦牡,通過一個(gè)實(shí)際項(xiàng)目的例子來說明相互轉(zhuǎn)換的代碼與具體的應(yīng)用友驮。
Step1. 設(shè)備臺(tái)賬的結(jié)構(gòu) AcountItem
。
/// <summary>
/// 臺(tái)賬Item
/// </summary>
public class AccountItem
{
/// <summary>
/// 設(shè)備ID
/// </summary>
public string EquipmentId
{
get;
set;
}
/// <summary>
/// 廠站名稱
/// </summary>
public string FactoryStationName
{
get;
set;
}
/// <summary>
/// 廠站類型
/// </summary>
public string FactoryStationType
{
get;
set;
}
/// <summary>
/// 一次設(shè)備名稱
/// </summary>
public string PrimaryDeviceName
{ get; set; }
/// <summary>
/// 一次設(shè)備電壓等級(jí)
/// </summary>
public string PrimaryDeviceVoltageLevel
{ get; set; }
/// <summary>
/// 制造廠家
/// </summary>
public string Manufacturer
{
get;
set;
}
/// <summary>
/// 保護(hù)類別
/// </summary>
public string ProtectionCategory
{
get;
set;
}
/// <summary>
/// 保護(hù)型號(hào)
/// </summary>
public string ProtectionType
{
get;
set;
}
/// <summary>
/// 軟件版本
/// </summary>
public string SoftwareVersion
{
get;
set;
}
/// <summary>
/// 保護(hù)名稱
/// </summary>
public string ProtectionName
{
get;
set;
}
/// <summary>
/// 投運(yùn)日期
/// </summary>
public string CommissionDate
{
get;
set;
}
/// <summary>
/// 出廠日期
/// </summary>
public string ProductionDate
{
get;
set;
}
/// <summary>
/// 所在屏柜
/// </summary>
public string ScreenCabinets
{
get;
set;
}
/// <summary>
/// 保護(hù)套別
/// </summary>
public string ProtectiveSleeve
{
get;
set;
}
}
Step2. 把模型類 List<T>
轉(zhuǎn)化為 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>
轉(zhuǎn)化為 DataTable
。
// 初始化鏈表并加入數(shù)據(jù)椭豫。
List<AccountItem> lst = new List<AccountItem>();
DataTable dt = ListToDataTable(lst);
dt
數(shù)據(jù)表列集合的列名依次為:
- EquipmentId
- FactoryStationName
- FactoryStationType
- PrimaryDeviceName
- PrimaryDeviceVoltageLevel
- Manufacturer
- ProtectionCategory
- ProtectionType
- SoftwareVersion
- ProtectionName
- CommissionDate
- ProductionDate
- ScreenCabinets
- ProtectiveSleeve;
Step4. DataTable 轉(zhuǎn)化為 List<T>耻瑟。
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
轉(zhuǎn)化為 List<AccountItem>
赏酥。
List<AccountItem> lst = DataTableToList(dt);
通過調(diào)用 Step4 帶約束的泛型方法喳整,可以得到模型類 List<AccountItem>
。
總結(jié)
到此為止裸扶,DataTable
與 List<T>
的相互轉(zhuǎn)換就介紹完了框都,由于整個(gè)項(xiàng)目都是利用 List<T>
來構(gòu)建邏輯的,所以整個(gè)系統(tǒng)可以具有良好的結(jié)構(gòu)呵晨,通過 LINQ 也能滿足效率的要求魏保。今天就到這里吧熬尺!See You!
相關(guān)圖文:
- 如何利用 C# 實(shí)現(xiàn) K 最鄰近算法谓罗?
- 如何利用 C# 實(shí)現(xiàn) K-D Tree 結(jié)構(gòu)粱哼?
- 如何利用 C# + KDTree 實(shí)現(xiàn) K 最鄰近算法?
- 如何利用 C# 對(duì)神經(jīng)網(wǎng)絡(luò)模型進(jìn)行抽象檩咱?
- 如何利用 C# 實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)的感知器模型揭措?
- 如何利用 C# 實(shí)現(xiàn) Delta 學(xué)習(xí)規(guī)則?
- 如何利用 C# 開發(fā)「桌面版百度翻譯」軟件刻蚯!
- 如何利用 C# 開發(fā)「股票數(shù)據(jù)分析軟件」(上)
- 如何利用 C# 開發(fā)「股票數(shù)據(jù)分析軟件」(中)
- 如何利用 C# 開發(fā)「股票數(shù)據(jù)分析軟件」(下)
- 如何利用 C# 爬取「財(cái)報(bào)說」中的股票數(shù)據(jù)绊含?
- 如何利用 C# 爬取 One 持有者返利數(shù)據(jù)!
- 如何利用 C# 爬取Gate.io交易所的公告芦倒!
- 如何利用 C# 爬取BigOne交易所的公告艺挪!
- 如何利用 C# 爬取 ONE 的交易數(shù)據(jù)?
- 如何利用 C# 爬取「京東 - 計(jì)算機(jī)與互聯(lián)網(wǎng)圖書銷量榜」兵扬!
- 如何利用 C# 爬取「當(dāng)當(dāng) - 計(jì)算機(jī)與互聯(lián)網(wǎng)圖書銷量榜」麻裳!
- 如何利用 C# 爬取「互動(dòng)出版網(wǎng) - 計(jì)算機(jī)圖書銷量榜」!
- 如何利用 C# 爬取「中國(guó)圖書網(wǎng) - 計(jì)算機(jī)與互聯(lián)網(wǎng)圖書銷量榜」器钟!
- 如何利用 C# 爬取「貓眼電影:熱映口碑榜」及對(duì)應(yīng)影片信息津坑!
- 如何利用 C# 爬取「貓眼電影專業(yè)版:票房」數(shù)據(jù)!
- 如何利用 C# 爬取「貓眼電影:最受期待榜」及對(duì)應(yīng)影片信息傲霸!
- 如何利用 C# 爬取「貓眼電影:國(guó)內(nèi)票房榜」及對(duì)應(yīng)影片信息疆瑰!
- 如何利用 C# + Python 破解貓眼電影的反爬蟲機(jī)制?
- 如何利用 C# 爬取帶 Token 驗(yàn)證的網(wǎng)站數(shù)據(jù)昙啄?