您的位置:首页 > 编程语言 > C#

C#中DataTable与泛型集合互转(支持泛型集合中对象包含枚举)

2017-05-11 11:49 337 查看
最近在做WCF,因为是内部接口,很多地方直接用的弱类型返回(DataSet),这其实是一种非常不好的方式,最近将项目做了修改,将所有接口返回值都修改成强类型,这样可以减少很多与客户端开发人员的沟通,结构内容一目了然

很多时候,后台我们通过ADO.NET使用SQL语句查询出了想要的数据,这时如果直接把这个DataSet丢给客户端开发人员,会让他们一头雾水,并且维护扩展起来都很麻烦,所以想了一个办法,在服务端,首先我们把查询到的数据集转换成泛型集合,再返回给客户端,客户端可以直接使用,也可以再自行转换成自己需要的数据格式,这样做还有一点是因为,DataTable在进行序列化与反序列化时并不那么可靠,记得在多线程同时序列化一个DataTable时会有异常,另外也隐藏了很多小问题,例如需要序列化DataTable的话必须设置TableName等等

首先是封装的辅助类,这个辅助类还可以完善,因为我这里数据库数据类型与实体对象的类型可以直接转换,如果实体类类型与数据库内类型不同,则需要做相应的转换

1 static class Helper
2     {
3         /// <summary>
4         ///  DataTable转换成泛型集合
5         /// </summary>
6         /// <typeparam name="T">泛型集合类型</typeparam>
7         /// <param name="dt">DataTable</param>
8         /// <param name="dEnum">字典集合,Key为需要从转换为enum项的DataColumnName,Value为需要转换的枚举的类型</param>
9         /// <returns>以实体类为元素的泛型集合</returns>
10         public static IList<T> DataTableConvertToListGenuric<T>(DataTable dt, Dictionary<string, Type> dEnum) where T : new()
11         {
12             if (dt?.Rows.Count > 0)
13             {
14                 // 定义集合
15                 List<T> ts = new List<T>();
16                 // 获得此模型的类型
17                 Type type = typeof(T);
18                 //定义一个临时变量
19                 string tempName = string.Empty;
20                 //遍历DataTable中所有的数据行
21                 foreach (DataRow dr in dt.Rows)
22                 {
23                     T t = new T();
24                     //如果T是值类型,则先进行装箱
25                     object obj = null;
26                     if (!t.GetType().IsClass)
27                     {
28                         obj = t;
29                     }
30                     //获得此模型的公共属性
31                     PropertyInfo[] propertys = t.GetType().GetProperties();
32                     //遍历该对象的所有属性
33                     foreach (PropertyInfo pi in propertys)
34                     {
35                         //将属性名称赋值给临时变量
36                         tempName = pi.Name;
37                         //检查DataTable是否包含此列(列名==对象的属性名)
38                         if (dt.Columns.Contains(tempName))
39                         {
40                             // 判断此属性是否有Setter
41                             if (!pi.CanWrite) continue;//该属性不可写,直接跳出
42                             //取值
43                             object value = dr[tempName];
44                             //如果非空,则赋给对象的属性
45                             if (value != DBNull.Value)
46                             {
47                                 //如果有枚举项
48                                 if (dEnum != null)
49                                 {
50                                     var queryResult = from n in dEnum
51                                                       where n.Key == tempName
52                                                       select n;
53                                     //枚举集合中包含与当前属性名相同的项
54                                     if (queryResult.Count() > 0)
55                                     {
56                                         if (obj != null)
57                                         {
58                                             //将字符串转换为枚举对象
59                                             pi.SetValue(obj, Enum.Parse(queryResult.FirstOrDefault().Value, value.ToString()), null);
60                                         }
61                                         else
62                                         {
63                                             //将字符串转换为枚举对象
64                                             pi.SetValue(t, Enum.Parse(queryResult.FirstOrDefault().Value, value.ToString()), null);
65                                         }
66                                     }
67                                     else
68                                     {
69                                         if (obj != null)
70                                         {
71                                             pi.SetValue(obj, value, null);
72                                         }
73                                         else
74                                         {
75                                             pi.SetValue(t, value, null);
76                                         }
77                                     }
78                                 }
79                                 else {
80                                     if (obj != null)
81                                     {
82                                         pi.SetValue(obj, value, null);
83                                     }
84                                     else
85                                     {
86                                         pi.SetValue(t, value, null);
87                                     }
88                                 }
89                             }
90                         }
91                     }
92                     T ta = default(T);
93                     //拆箱
94                     if (obj != null)
95                     {
96                         ta = (T)obj;
97                     }
98                     else
99                     {
100                         ta = t;
101                     }
102                     //对象添加到泛型集合中
103                     ts.Add(ta);
104                 }
105                 return ts;
106             }
107             else
108             {
109                 throw new ArgumentNullException("转换的集合为空.");
110             }
111         }
112
113         /// <summary>
114         /// 泛型集合转换成DataTable
115         /// </summary>
116         /// <typeparam name="T">泛型集合类型</typeparam>
117         /// <param name="list">泛型集合对象</param>
118         /// <returns></returns>
119         public static DataTable ListGenuricConvertToDataTable<T>(List<T> list)
120         {
121             if (list?.Count > 0)
122             {
123                 Type type = typeof(T);
124                 PropertyInfo[] properties = type.GetProperties();
125                 DataTable dt = new DataTable(type.Name);
126                 foreach (var item in properties)
127                 {
128                     dt.Columns.Add(new DataColumn(item.Name) { DataType = item.PropertyType });
129                 }
130                 foreach (var item in list)
131                 {
132                     DataRow row = dt.NewRow();
133                     foreach (var property in properties)
134                     {
135                         row[property.Name] = property.GetValue(item, null);
136                     }
137                     dt.Rows.Add(row);
138                 }
139                 return dt;
140             }
141             else
142             {
143                 throw new ArgumentNullException("转换的集合为空.");
144             }
145         }
146     }


下面是测试代码

1     class Program
2     {
3         static void Main(string[] args)
4         {
5             DataTable dt = new DataTable();
6             dt.Columns.Add("ID", typeof(int));
7             dt.Columns.Add("Name", typeof(string));
8             dt.Columns.Add("USex", typeof(string));
9             dt.Rows.Add(1, "肖潇",Sex.woman);
10             dt.Rows.Add(2, "何峰涛", Sex.man);
11             dt.Rows.Add(3, "王萌", Sex.woman);
12             dt.Rows.Add(4, "汤晓乐", Sex.man);
13             Dictionary<string, Type> dEnum = new Dictionary<string, Type>();
14             dEnum.Add("USex", typeof(Sex));
15             List<User> liUser = (List<User>)Helper.DataTableConvertToListGenuric<User>(dt, dEnum);
16             Console.WriteLine("DataTable To List<T>");
17             foreach (var item in liUser)
18             {
19                 Console.WriteLine(item.ID + ":" + item.Name+":"+item.USex);
20             }
21             Console.WriteLine("================");
22             DataTable dtConvert = Helper.ListGenuricConvertToDataTable(liUser);
23             Console.WriteLine("List<T> To DataTable");
24             foreach (DataRow item in dtConvert.Rows)
25             {
26                 Console.WriteLine(item["ID"] + ":" + item["Name"]+":"+(Sex)item["USex"]);
27             }
28             Console.ReadKey();
29         }
30     }
31
32     struct User
33     {
34         public int ID { get; set; }
35         public string Name { get; set; }
36         public Sex USex { get; set; }
37     }
38
39     enum Sex {
40         man = 0,
41         woman = 1
42     }


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐