我們都知道,在機房重構中,剛開始看的三層視頻,返回值類型是實體,後來用了SqlHelper,返回值類型就變成了Datatable,那這些,和今天要說的泛型有什麼關系呢?或者說,我們為什麼要大費周折的去用泛型呢?
原理

實體類即數據庫的映射,因此實體類中的屬性和數據庫表中的字段是相對應的。把DataTable中的每一行記錄視為一個實體類,把其中的字段讀取出來,存放到實體類的屬性中,再把所有的實體類存在泛型集合中。因此,DataTable中有多少個記錄,泛型集合中就有多少個實體類,每個實體類的屬性和DataTable的字段是相對應的。
1、編寫B層的人員無需手動填寫需要的字段,直接按一下點,全都提示出來了,想用哪個用哪個,不會出現寫錯的情況。
2、不必了解數據庫結構。
3、符合面向對象思想。
4、實體類的屬性是強類型,每個字段的類型都是已知的。
1、實體類的屬性名必須和數據庫表中的字段名一模一樣。
2、想用這種方法把DataTable轉換成實體類,必須有已知的實體類和DataTable中的數據相對應,也就是說必須明確你要轉換成的實體類類型,否則沒辦法指定泛型集合的類型,也就沒辦法調用。
3、各個表的字段盡量區別開來,不要相同。比如A表有個name字段,B表也有一個name字段,就不合理了。
說了這麼多,那麼,到底如何來實現Datatable轉泛型呢?我們先看代碼。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Collections;
using System.Reflection;
namespace SqlDAL
{
public class ConvertHelper
{
public List convertToList(DataTable dt) where T : new()
{
// 定義集合
List ts = new List();
// 獲得此模型的類型
Type type = typeof(T);
//定義一個臨時變量
string tempName = string.Empty;
//遍歷DataTable中所有的數據行
foreach (DataRow dr in dt.Rows)
{
T t = new T();
// 獲得此模型的公共屬性
PropertyInfo[] propertys = t.GetType().GetProperties();
//遍歷該對象的所有屬性
foreach (PropertyInfo pi in propertys)
{
tempName = pi.Name;//將屬性名稱賦值給臨時變量
//檢查DataTable是否包含此列(列名==對象的屬性名)
if (dt.Columns.Contains(tempName))
{
// 判斷此屬性是否有Setter
if (!pi.CanWrite) continue;//該屬性不可寫,直接跳出
//取值
object value = dr[tempName];
//如果非空,則賦給對象的屬性
if (value != DBNull.Value)
pi.SetValue(t, value, null);
}
}
//對象添加到泛型集合中
ts.Add(t);
}
return ts;
}
}
}
DataTable table =SqlDAL.SQLHelper.GetDataTable(sql, CommandType.Text, sqlParams);//調用SqlHelper中的有返回值的方法
if (table.Rows.Count > 0)
{
ConvertHelper ctl = new ConvertHelper();
List list = new List();
list = ctl.convertToList(table);
return list;
}
else { return null; }
txtRate.Text = list[0].Rate.ToString(); txtTmpRate.Text = list[0].TmpRate.ToString(); txtPrepare.Text = list[0].PrepareTime.ToString(); txtLimit.Text = list[0].LimitCash.ToString(); lblModUser.Text = list[0].Head.ToString();
想要做出來一個功能,有很多方法,我們的任務不僅僅是掌握這些方法,更重要的是分析這些方法,區別這些方法,找到它們各自的優缺點,這樣才能更好的使用這些方法。