背景:
開發工作中經常需要類型的轉換,比如DataTable轉換為List、或是DataTable轉換為JSON等等,
每次都重復的寫相同的代碼,比如:把實體類的字段屬性一個一個的列出來,從DataTabel中把值取出來賦上,
真的好麻煩 (*=*)
思考:
1)DataTable轉換為List,主要是使用反射,遍歷實體類的屬性,和DataTabel中的列進行對比並賦值
2)DataTable轉換為JSON,主要是拼接JSON串
實踐:
參考了網上很多前輩的思路和實現,制作了一個ConvertHelper類,感謝各位前輩 ^_^
轉換輔助類ConvertHelper代碼如下,覆蓋范圍包括屬性和公共字段:

1 /// <summary> 2 /// 轉換輔助類 3 /// </summary> 4 /// <typeparam name="T"></typeparam> 5 public class ConvertHelper<T> where T : new() 6 { 7 /// <summary> 8 /// DataTable-->List 9 /// </summary> 10 /// <param name="dt">DataTable</param> 11 /// <returns></returns> 12 public static IList<T> DataTableConvertToList(DataTable dt) 13 { 14 IList<T> ts = new List<T>(); 15 16 // 取得泛型的類型 17 Type type = typeof(T); 18 19 // 創建類型的對象(用於比較用) 20 //object convertObj = Activator.CreateInstance(type, null); 21 22 // 反射取得類型實例的屬性數組 23 //PropertyInfo[] propertys = convertObj.GetType().GetProperties(); 24 PropertyInfo[] propertys = type.GetProperties(); 25 26 // 反射取得類型實例的字段數組 27 FieldInfo[] fields = type.GetFields(); 28 29 foreach (DataRow dr in dt.Rows) 30 { 31 // 創建類型的對象(用於賦值用) 32 //object outputObj = Activator.CreateInstance(type, null); 33 T outputObj = new T(); 34 35 // 遍歷字段(公共字段) 36 foreach (FieldInfo fi in fields) 37 { 38 // 如果DataTable的數據列中包含有對應的字段 39 if (dt.Columns.Contains(fi.Name)) 40 { 41 // 取得字段的值 42 object value = dr[fi.Name]; 43 44 if (value != DBNull.Value) 45 { 46 // 將對應字段的值賦給創建的類型實例的對應的字段 47 fi.SetValue(outputObj, value); 48 } 49 } 50 } 51 52 // 遍歷屬性 53 foreach (PropertyInfo pi in propertys) 54 { 55 // 如果DataTable的數據列中包含有對應的屬性 56 if (dt.Columns.Contains(pi.Name)) 57 { 58 if (!pi.CanWrite) 59 { 60 continue; 61 } 62 63 // 取得屬性的值 64 object value = dr[pi.Name]; 65 66 if (value != DBNull.Value) 67 { 68 // 將對應屬性的值賦給創建的類型實例的對應的屬性 69 pi.SetValue(outputObj, value, null); 70 } 71 } 72 } 73 74 // 添加到List中 75 ts.Add((T)outputObj); 76 } 77 78 return ts; 79 } 80 81 /// <summary> 82 /// DataTable-->Json 83 /// </summary> 84 /// <param name="dt">DataTable</param> 85 /// <returns></returns> 86 public static string DataTableConvertToJson(DataTable dt) 87 { 88 StringBuilder jsonBuilder = new StringBuilder(); 89 90 // 拼接JSON串 91 jsonBuilder.Append("{\""); 92 jsonBuilder.Append(dt.TableName); 93 jsonBuilder.Append("\":["); 94 for (int i = 0; i < dt.Rows.Count; i++) 95 { 96 jsonBuilder.Append("{"); 97 for (int j = 0; j < dt.Columns.Count; j++) 98 { 99 jsonBuilder.Append("\""); 100 jsonBuilder.Append(dt.Columns[j].ColumnName); 101 jsonBuilder.Append("\":\""); 102 jsonBuilder.Append(dt.Rows[i][j].ToString()); 103 jsonBuilder.Append("\","); 104 } 105 jsonBuilder.Remove(jsonBuilder.Length - 1, 1); 106 jsonBuilder.Append("},"); 107 } 108 jsonBuilder.Remove(jsonBuilder.Length - 1, 1); 109 jsonBuilder.Append("]"); 110 jsonBuilder.Append("}"); 111 112 return jsonBuilder.ToString(); 113 } 114 115 /// <summary> 116 /// DataSet-->Json 117 /// </summary> 118 /// <param name="ds">DataSet</param> 119 /// <returns></returns> 120 public static string DataSetConvertToJson(DataSet ds) 121 { 122 StringBuilder json = new StringBuilder(); 123 124 foreach (DataTable dt in ds.Tables) 125 { 126 // 拼接JSON串 127 json.Append("{\""); 128 json.Append(dt.TableName); 129 json.Append("\":"); 130 json.Append(DataTableConvertToJson(dt)); 131 json.Append("}"); 132 } 133 134 return json.ToString(); 135 } 136 }
如何使用呢?
很方便的,先定義一個實體類UserInfo,定義了13個字段

1 /// <summary> 2 /// 用戶信息實體 3 /// </summary> 4 public class UserInfo 5 { 6 /// <summary> 7 /// 用戶編號 8 /// </summary> 9 public int UserID { get; set; } 10 11 /// <summary> 12 /// 用戶姓名 13 /// </summary> 14 public string UserName { get; set; } 15 16 /// <summary> 17 /// 性別 18 /// </summary> 19 public string Gender { get; set; } 20 21 /// <summary> 22 /// 身高 23 /// </summary> 24 public decimal Height { get; set; } 25 26 /// <summary> 27 /// 體重 28 /// </summary> 29 public decimal Weight { get; set; } 30 31 /// <summary> 32 /// 生日 33 /// </summary> 34 public DateTime Birthday { get; set; } 35 36 /// <summary> 37 /// 出生地 38 /// </summary> 39 public string HomeTown { get; set; } 40 41 /// <summary> 42 /// 部門 43 /// </summary> 44 public string Department { get; set; } 45 46 /// <summary> 47 /// 職級 48 /// </summary> 49 public string Level { get; set; } 50 51 /// <summary> 52 /// 用戶薪資 53 /// </summary> 54 public decimal Salary { get; set; } 55 56 /// <summary> 57 /// 愛好 58 /// </summary> 59 public string Hobby { get; set; } 60 61 /// <summary> 62 /// 學歷 63 /// </summary> 64 public string Degress = string.Empty; 65 66 /// <summary> 67 /// 年齡 68 /// </summary> 69 public int Age = 0; 70 }
再定義一個方法填充一些數據模擬DataTable,這里填充了50w條記錄

1 /// <summary> 2 /// 模擬數據 3 /// </summary> 4 /// <returns></returns> 5 private static DataTable MockData() 6 { 7 DataTable dt = new DataTable("UserInfo"); 8 9 // 添加數據列 10 DataColumn dc = null; 11 12 dc = dt.Columns.Add("UserID", Type.GetType("System.Int32")); 13 dc.AutoIncrement = true; //自動增加 14 dc.AutoIncrementSeed = 1; //起始為1 15 dc.AutoIncrementStep = 1; //步長為1 16 dc.AllowDBNull = false; 17 18 dc = dt.Columns.Add("UserName", Type.GetType("System.String")); 19 dc = dt.Columns.Add("Gender", Type.GetType("System.String")); 20 dc = dt.Columns.Add("Height", Type.GetType("System.Decimal")); 21 dc = dt.Columns.Add("Weight", Type.GetType("System.Decimal")); 22 dc = dt.Columns.Add("Birthday", Type.GetType("System.DateTime")); 23 dc = dt.Columns.Add("HomeTown", Type.GetType("System.String")); 24 dc = dt.Columns.Add("Department", Type.GetType("System.String")); 25 dc = dt.Columns.Add("Level", Type.GetType("System.String")); 26 dc = dt.Columns.Add("Salary", Type.GetType("System.Decimal")); 27 dc = dt.Columns.Add("Hobby", Type.GetType("System.String")); 28 dc = dt.Columns.Add("Degress", Type.GetType("System.String")); 29 dc = dt.Columns.Add("Age", Type.GetType("System.Int32")); 30 31 32 #region 添加數據行 33 34 // 方式1 35 //DataRow dr = null; 36 37 //dr = dt.NewRow(); 38 //dr["UserName"] = "洪自軍"; 39 //dr["Salary"] = 123.45; 40 //dt.Rows.Add(dr); 41 42 //dr = dt.NewRow(); 43 //dr["UserName"] = "武建昌"; 44 //dr["Salary"] = 987.65; 45 //dt.Rows.Add(dr); 46 47 // 方式2 48 //dt.Rows.Add(new object[] { null, "張洋", 123.45 }); 49 //dt.Rows.Add(new object[] { null, "張兄家", 987.65 }); 50 //dt.Rows.Add(new object[] { null, "王生傑", 111.11 }); 51 //dt.Rows.Add(new object[] { null, "呉QQ", 888.88 }); 52 //dt.Rows.Add(new object[] { null, "劉瑞", 222.22 }); 53 54 for (int i = 0; i < 500000; i++) 55 { 56 dt.Rows.Add(new object[] { 57 null, "測試" + i, "女", 123.45, 543.21, 58 "1990-02-14", "火星", "碼農組", "碼農", 250.13, "吃喝玩樂", 59 1127963, 20 60 }); 61 } 62 63 #endregion 64 65 return dt; 66 }
調用轉換輔助類進行轉換

1 /// <summary> 2 /// DataTable-->List測試 3 /// </summary> 4 private static void MockDataTableConvertToList() 5 { 6 // 定義時間起點 7 TimeSpan tsStart = new TimeSpan(DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); 8 9 // 変換処理 10 IList<UserInfo> users = ConvertHelper<UserInfo>.DataTableConvertToList(MockData()); 11 12 // 定義時間終點 13 TimeSpan tsEnd = new TimeSpan(DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); 14 15 // 計算耗時 16 TimeSpan ts = tsStart.Subtract(tsEnd).Duration(); 17 18 Console.WriteLine(string.Format("DataTable-->List 変換耗時:{0}", ts.ToString())); 19 20 //foreach (var user in users) 21 //{ 22 // Console.WriteLine("{0} : {1} - {2};", user.UserID, user.UserName, user.Salary); 23 //} 24 } 25 26 /// <summary> 27 /// DataTable-->Json測試 28 /// </summary> 29 private static void MockDataTableConvertToJson() 30 { 31 // 定義時間起點 32 TimeSpan tsStart = new TimeSpan(DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); 33 34 // 変換処理 35 string jsonString = ConvertHelper<UserInfo>.DataTableConvertToJson(MockData()); 36 37 // 定義時間終點 38 TimeSpan tsEnd = new TimeSpan(DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second, DateTime.Now.Millisecond); 39 40 // 計算耗時 41 TimeSpan ts = tsStart.Subtract(tsEnd).Duration(); 42 43 Console.WriteLine(string.Format("DataTable-->Json 変換耗時:{0}", ts.ToString())); 44 45 //Console.WriteLine(jsonString); 46 }
兩句代碼完成
IList<UserInfo> users = ConvertHelper<UserInfo>.DataTableConvertToList(MockData()); string jsonString = ConvertHelper<UserInfo>.DataTableConvertToJson(MockData());
可以看到轉換后的效果
前幾條數據是DataTable轉換為List的效果,后一條數據是DataTable轉換為JSON的效果
再貼一張類型轉換時間的測試結果吧,50w條記錄轉換10秒左右
是不是很簡單呢?
如果您有好的實現或是意見,別忘了告訴我哦 ^_^