【原】超簡單類型轉換(DataTable --> List/JSON)的實現


背景:

開發工作中經常需要類型的轉換,比如DataTable轉換為List、或是DataTable轉換為JSON等等,

每次都重復的寫相同的代碼,比如:把實體類的字段屬性一個一個的列出來,從DataTabel中把值取出來賦上,

真的好麻煩 (*=*)

思考:

1)DataTable轉換為List,主要是使用反射,遍歷實體類的屬性,和DataTabel中的列進行對比並賦值

2)DataTable轉換為JSON,主要是拼接JSON串

實踐:

參考了網上很多前輩的思路和實現,制作了一個ConvertHelper類,感謝各位前輩 ^_^

轉換輔助類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個字段

UserInfo
 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條記錄

MockData
 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秒左右

是不是很簡單呢?

如果您有好的實現或是意見,別忘了告訴我哦 ^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM