【原】超简单类型转换(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秒左右

是不是很简单呢?

如果您有好的实现或是意见,别忘了告诉我哦 ^_^

posted @   {name:"代码屠夫"}  阅读(3833)  评论(11编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示