DataTableHelper.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Reflection;
  6. namespace Masuit.Tools.Database
  7. {
  8. /// <summary>
  9. /// DataTable帮助类
  10. /// </summary>
  11. public static class DataTableHelper
  12. {
  13. /// <summary>
  14. /// 给DataTable增加一个自增列
  15. /// 如果DataTable 存在 identityid 字段 则 直接返回DataTable 不做任何处理
  16. /// </summary>
  17. /// <param name="dt">DataTable</param>
  18. /// <returns>返回Datatable 增加字段 identityid </returns>
  19. /// <exception cref="DuplicateNameException">The collection already has a column with the specified name. (The comparison is not case-sensitive.) </exception>
  20. public static DataTable AddIdentityColumn(this DataTable dt)
  21. {
  22. if (!dt.Columns.Contains("identityid"))
  23. {
  24. dt.Columns.Add("identityid");
  25. for (int i = 0; i < dt.Rows.Count; i++)
  26. {
  27. dt.Rows[i]["identityid"] = (i + 1).ToString();
  28. }
  29. }
  30. return dt;
  31. }
  32. /// <summary>
  33. /// 检查DataTable 是否有数据行
  34. /// </summary>
  35. /// <param name="dt">DataTable</param>
  36. /// <returns>是否有数据行</returns>
  37. public static bool IsHaveRows(this DataTable dt)
  38. {
  39. if (dt?.Rows.Count > 0)
  40. return true;
  41. return false;
  42. }
  43. /// <summary>
  44. /// DataTable转换成实体列表
  45. /// </summary>
  46. /// <typeparam name="T">实体 T </typeparam>
  47. /// <param name="table">datatable</param>
  48. /// <returns>强类型的数据集合</returns>
  49. public static IList<T> DataTableToList<T>(this DataTable table) where T : class
  50. {
  51. if (!IsHaveRows(table))
  52. return new List<T>();
  53. IList<T> list = new List<T>();
  54. foreach (DataRow dr in table.Rows)
  55. {
  56. var model = Activator.CreateInstance<T>();
  57. foreach (DataColumn dc in dr.Table.Columns)
  58. {
  59. object drValue = dr[dc.ColumnName];
  60. PropertyInfo pi = model.GetType().GetProperty(dc.ColumnName);
  61. if (pi != null && pi.CanWrite && (drValue != null && !Convert.IsDBNull(drValue)))
  62. {
  63. pi.SetValue(model, drValue, null);
  64. }
  65. }
  66. list.Add(model);
  67. }
  68. return list;
  69. }
  70. /// <summary>
  71. /// 实体列表转换成DataTable
  72. /// </summary>
  73. /// <typeparam name="T">实体</typeparam>
  74. /// <param name="list"> 实体列表</param>
  75. /// <returns>映射为数据表</returns>
  76. /// <exception cref="OverflowException">The array is multidimensional and contains more than <see cref="F:System.Int32.MaxValue" /> elements.</exception>
  77. public static DataTable ListToDataTable<T>(this IList<T> list) where T : class
  78. {
  79. if (list == null || list.Count <= 0)
  80. {
  81. return null;
  82. }
  83. var dt = new DataTable(typeof(T).Name);
  84. PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
  85. int length = myPropertyInfo.Length;
  86. bool createColumn = true;
  87. foreach (T t in list)
  88. {
  89. if (t == null)
  90. {
  91. continue;
  92. }
  93. var row = dt.NewRow();
  94. for (int i = 0; i < length; i++)
  95. {
  96. PropertyInfo pi = myPropertyInfo[i];
  97. string name = pi.Name;
  98. if (createColumn)
  99. {
  100. var column = new DataColumn(name, pi.PropertyType);
  101. dt.Columns.Add(column);
  102. }
  103. row[name] = pi.GetValue(t, null);
  104. }
  105. if (createColumn)
  106. {
  107. createColumn = false;
  108. }
  109. dt.Rows.Add(row);
  110. }
  111. return dt;
  112. }
  113. /// <summary>
  114. /// 将泛型集合类转换成DataTable
  115. /// </summary>
  116. /// <typeparam name="T">集合项类型</typeparam>
  117. /// <param name="list">集合</param>
  118. /// <returns>数据集(表)</returns>
  119. public static DataTable ToDataTable<T>(this IList<T> list)
  120. {
  121. return ToDataTable<T>(list, null);
  122. }
  123. /// <summary>
  124. /// 将泛型集合类转换成DataTable
  125. /// </summary>
  126. /// <typeparam name="T">集合项类型</typeparam>
  127. /// <param name="list">集合</param>
  128. /// <param name="propertyName">需要返回的列的列名</param>
  129. /// <returns>数据集(表)</returns>
  130. public static DataTable ToDataTable<T>(this IList<T> list, params string[] propertyName)
  131. {
  132. List<string> propertyNameList = new List<string>();
  133. if (propertyName != null)
  134. propertyNameList.AddRange(propertyName);
  135. DataTable result = new DataTable();
  136. if (list.Count > 0)
  137. {
  138. PropertyInfo[] propertys = list[0].GetType().GetProperties();
  139. propertys.ForEach(pi =>
  140. {
  141. if (propertyNameList.Count == 0)
  142. {
  143. result.Columns.Add(pi.Name, pi.PropertyType);
  144. }
  145. else
  146. {
  147. if (propertyNameList.Contains(pi.Name))
  148. {
  149. result.Columns.Add(pi.Name, pi.PropertyType);
  150. }
  151. }
  152. });
  153. list.ForEach(item =>
  154. {
  155. ArrayList tempList = new ArrayList();
  156. foreach (PropertyInfo pi in propertys)
  157. {
  158. if (propertyNameList.Count == 0)
  159. {
  160. object obj = pi.GetValue(item, null);
  161. tempList.Add(obj);
  162. }
  163. else
  164. {
  165. if (propertyNameList.Contains(pi.Name))
  166. {
  167. object obj = pi.GetValue(item, null);
  168. tempList.Add(obj);
  169. }
  170. }
  171. }
  172. object[] array = tempList.ToArray();
  173. result.LoadDataRow(array, true);
  174. });
  175. }
  176. return result;
  177. }
  178. /// <summary>
  179. /// 根据nameList里面的字段创建一个表格,返回该表格的DataTable
  180. /// </summary>
  181. /// <param name="nameList">包含字段信息的列表</param>
  182. /// <returns>DataTable</returns>
  183. public static DataTable CreateTable(this List<string> nameList)
  184. {
  185. if (nameList.Count <= 0)
  186. return null;
  187. var myDataTable = new DataTable();
  188. foreach (string columnName in nameList)
  189. {
  190. myDataTable.Columns.Add(columnName, typeof(string));
  191. }
  192. return myDataTable;
  193. }
  194. /// <summary>
  195. /// 通过字符列表创建表字段,字段格式可以是:<br/>
  196. /// 1) a,b,c,d,e<br/>
  197. /// 2) a|int,b|string,c|bool,d|decimal<br/>
  198. /// </summary>
  199. /// <param name="dt"></param>
  200. /// <param name="nameString">字符列表</param>
  201. /// <returns>内存表</returns>
  202. public static DataTable CreateTable(this DataTable dt, string nameString)
  203. {
  204. string[] nameArray = nameString.Split(',', ';');
  205. foreach (string item in nameArray)
  206. {
  207. if (!string.IsNullOrEmpty(item))
  208. {
  209. string[] subItems = item.Split('|');
  210. if (subItems.Length == 2)
  211. {
  212. dt.Columns.Add(subItems[0], ConvertType(subItems[1]));
  213. }
  214. else
  215. {
  216. dt.Columns.Add(subItems[0]);
  217. }
  218. }
  219. }
  220. return dt;
  221. }
  222. /// <summary>
  223. /// 根据类型名返回一个Type类型
  224. /// </summary>
  225. /// <param name="typeName">类型的名称</param>
  226. /// <returns>Type对象</returns>
  227. private static Type ConvertType(string typeName)
  228. {
  229. typeName = typeName.ToLower().Replace("system.", "");
  230. Type newType = typeof(string);
  231. switch (typeName)
  232. {
  233. case "boolean":
  234. case "bool":
  235. newType = typeof(bool);
  236. break;
  237. case "int16":
  238. case "short":
  239. newType = typeof(short);
  240. break;
  241. case "int32":
  242. case "int":
  243. newType = typeof(int);
  244. break;
  245. case "long":
  246. case "int64":
  247. newType = typeof(long);
  248. break;
  249. case "uint16":
  250. case "ushort":
  251. newType = typeof(ushort);
  252. break;
  253. case "uint32":
  254. case "uint":
  255. newType = typeof(uint);
  256. break;
  257. case "uint64":
  258. case "ulong":
  259. newType = typeof(ulong);
  260. break;
  261. case "single":
  262. case "float":
  263. newType = typeof(float);
  264. break;
  265. case "string":
  266. newType = typeof(string);
  267. break;
  268. case "guid":
  269. newType = typeof(Guid);
  270. break;
  271. case "decimal":
  272. newType = typeof(decimal);
  273. break;
  274. case "double":
  275. newType = typeof(double);
  276. break;
  277. case "datetime":
  278. newType = typeof(DateTime);
  279. break;
  280. case "byte":
  281. newType = typeof(byte);
  282. break;
  283. case "char":
  284. newType = typeof(char);
  285. break;
  286. }
  287. return newType;
  288. }
  289. /// <summary>
  290. /// 获得从DataRowCollection转换成的DataRow数组
  291. /// </summary>
  292. /// <param name="drc">DataRowCollection</param>
  293. /// <returns>DataRow数组</returns>
  294. public static DataRow[] GetDataRowArray(this DataRowCollection drc)
  295. {
  296. int count = drc.Count;
  297. DataRow[] drs = new DataRow[count];
  298. for (int i = 0; i < count; i++)
  299. {
  300. drs[i] = drc[i];
  301. }
  302. return drs;
  303. }
  304. /// <summary>
  305. /// 将DataRow数组转换成DataTable,注意行数组的每个元素须具有相同的数据结构,
  306. /// 否则当有元素长度大于第一个元素时,抛出异常
  307. /// </summary>
  308. /// <param name="rows">行数组</param>
  309. /// <returns>将内存行组装成内存表</returns>
  310. public static DataTable GetTableFromRows(this DataRow[] rows)
  311. {
  312. if (rows.Length <= 0)
  313. {
  314. return new DataTable();
  315. }
  316. DataTable dt = rows[0].Table.Clone();
  317. dt.DefaultView.Sort = rows[0].Table.DefaultView.Sort;
  318. for (int i = 0; i < rows.Length; i++)
  319. {
  320. dt.LoadDataRow(rows[i].ItemArray, true);
  321. }
  322. return dt;
  323. }
  324. /// <summary>
  325. /// 排序表的视图
  326. /// </summary>
  327. /// <param name="dt">原内存表</param>
  328. /// <param name="sorts">排序方式</param>
  329. /// <returns>排序后的内存表</returns>
  330. public static DataTable SortedTable(this DataTable dt, params string[] sorts)
  331. {
  332. if (dt.Rows.Count > 0)
  333. {
  334. string tmp = "";
  335. for (int i = 0; i < sorts.Length; i++)
  336. {
  337. tmp += sorts[i] + ",";
  338. }
  339. dt.DefaultView.Sort = tmp.TrimEnd(',');
  340. }
  341. return dt;
  342. }
  343. /// <summary>
  344. /// 根据条件过滤表的内容
  345. /// </summary>
  346. /// <param name="dt">原内存表</param>
  347. /// <param name="condition">过滤条件</param>
  348. /// <returns>过滤后的内存表</returns>
  349. public static DataTable FilterDataTable(this DataTable dt, string condition)
  350. {
  351. if (condition.Trim().Length == 0)
  352. {
  353. return dt;
  354. }
  355. var newdt = dt.Clone();
  356. DataRow[] dr = dt.Select(condition);
  357. dr.ForEach(t => newdt.ImportRow(t));
  358. return newdt;
  359. }
  360. }
  361. }