DataTableHelper.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Reflection;
  6. namespace Masuit.Tools.Core.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 HasRows(this DataTable dt)
  38. {
  39. return dt.Rows.Count > 0;
  40. }
  41. /// <summary>
  42. /// DataTable转换成实体列表
  43. /// </summary>
  44. /// <typeparam name="T">实体 T </typeparam>
  45. /// <param name="table">datatable</param>
  46. /// <returns>强类型的数据集合</returns>
  47. public static IList<T> DataTableToList<T>(this DataTable table) where T : class
  48. {
  49. if (!HasRows(table))
  50. {
  51. return new List<T>();
  52. }
  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(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. {
  135. propertyNameList.AddRange(propertyName);
  136. }
  137. DataTable result = new DataTable();
  138. if (list.Count <= 0)
  139. {
  140. return result;
  141. }
  142. PropertyInfo[] propertys = list[0].GetType().GetProperties();
  143. propertys.ForEach(pi =>
  144. {
  145. if (propertyNameList.Count == 0)
  146. {
  147. result.Columns.Add(pi.Name, pi.PropertyType);
  148. }
  149. else
  150. {
  151. if (propertyNameList.Contains(pi.Name))
  152. {
  153. result.Columns.Add(pi.Name, pi.PropertyType);
  154. }
  155. }
  156. });
  157. list.ForEach(item =>
  158. {
  159. ArrayList tempList = new ArrayList();
  160. foreach (PropertyInfo pi in propertys)
  161. {
  162. if (propertyNameList.Count == 0)
  163. {
  164. object obj = pi.GetValue(item, null);
  165. tempList.Add(obj);
  166. }
  167. else
  168. {
  169. if (propertyNameList.Contains(pi.Name))
  170. {
  171. object obj = pi.GetValue(item, null);
  172. tempList.Add(obj);
  173. }
  174. }
  175. }
  176. object[] array = tempList.ToArray();
  177. result.LoadDataRow(array, true);
  178. });
  179. return result;
  180. }
  181. /// <summary>
  182. /// 根据nameList里面的字段创建一个表格,返回该表格的DataTable
  183. /// </summary>
  184. /// <param name="nameList">包含字段信息的列表</param>
  185. /// <returns>DataTable</returns>
  186. public static DataTable CreateTable(this List<string> nameList)
  187. {
  188. if (nameList.Count <= 0)
  189. {
  190. return null;
  191. }
  192. var myDataTable = new DataTable();
  193. foreach (string columnName in nameList)
  194. {
  195. myDataTable.Columns.Add(columnName, typeof(string));
  196. }
  197. return myDataTable;
  198. }
  199. /// <summary>
  200. /// 通过字符列表创建表字段,字段格式可以是:<br/>
  201. /// 1) a,b,c,d,e<br/>
  202. /// 2) a|int,b|string,c|bool,d|decimal<br/>
  203. /// </summary>
  204. /// <param name="dt"></param>
  205. /// <param name="nameString">字符列表</param>
  206. /// <returns>内存表</returns>
  207. public static DataTable CreateTable(this DataTable dt, string nameString)
  208. {
  209. string[] nameArray = nameString.Split(',', ';');
  210. foreach (string item in nameArray)
  211. {
  212. if (!string.IsNullOrEmpty(item))
  213. {
  214. string[] subItems = item.Split('|');
  215. if (subItems.Length == 2)
  216. {
  217. dt.Columns.Add(subItems[0], ConvertType(subItems[1]));
  218. }
  219. else
  220. {
  221. dt.Columns.Add(subItems[0]);
  222. }
  223. }
  224. }
  225. return dt;
  226. }
  227. /// <summary>
  228. /// 根据类型名返回一个Type类型
  229. /// </summary>
  230. /// <param name="typeName">类型的名称</param>
  231. /// <returns>Type对象</returns>
  232. private static Type ConvertType(string typeName)
  233. {
  234. typeName = typeName.ToLower().Replace("system.", "");
  235. Type newType = typeof(string);
  236. switch (typeName)
  237. {
  238. case "boolean":
  239. case "bool":
  240. newType = typeof(bool);
  241. break;
  242. case "int16":
  243. case "short":
  244. newType = typeof(short);
  245. break;
  246. case "int32":
  247. case "int":
  248. newType = typeof(int);
  249. break;
  250. case "long":
  251. case "int64":
  252. newType = typeof(long);
  253. break;
  254. case "uint16":
  255. case "ushort":
  256. newType = typeof(ushort);
  257. break;
  258. case "uint32":
  259. case "uint":
  260. newType = typeof(uint);
  261. break;
  262. case "uint64":
  263. case "ulong":
  264. newType = typeof(ulong);
  265. break;
  266. case "single":
  267. case "float":
  268. newType = typeof(float);
  269. break;
  270. case "string":
  271. newType = typeof(string);
  272. break;
  273. case "guid":
  274. newType = typeof(Guid);
  275. break;
  276. case "decimal":
  277. newType = typeof(decimal);
  278. break;
  279. case "double":
  280. newType = typeof(double);
  281. break;
  282. case "datetime":
  283. newType = typeof(DateTime);
  284. break;
  285. case "byte":
  286. newType = typeof(byte);
  287. break;
  288. case "char":
  289. newType = typeof(char);
  290. break;
  291. }
  292. return newType;
  293. }
  294. /// <summary>
  295. /// 获得从DataRowCollection转换成的DataRow数组
  296. /// </summary>
  297. /// <param name="drc">DataRowCollection</param>
  298. /// <returns>DataRow数组</returns>
  299. public static DataRow[] GetDataRowArray(this DataRowCollection drc)
  300. {
  301. int count = drc.Count;
  302. DataRow[] drs = new DataRow[count];
  303. for (int i = 0; i < count; i++)
  304. {
  305. drs[i] = drc[i];
  306. }
  307. return drs;
  308. }
  309. /// <summary>
  310. /// 将DataRow数组转换成DataTable,注意行数组的每个元素须具有相同的数据结构,
  311. /// 否则当有元素长度大于第一个元素时,抛出异常
  312. /// </summary>
  313. /// <param name="rows">行数组</param>
  314. /// <returns>将内存行组装成内存表</returns>
  315. public static DataTable GetTableFromRows(this DataRow[] rows)
  316. {
  317. if (rows.Length <= 0)
  318. {
  319. return new DataTable();
  320. }
  321. DataTable dt = rows[0].Table.Clone();
  322. dt.DefaultView.Sort = rows[0].Table.DefaultView.Sort;
  323. for (int i = 0; i < rows.Length; i++)
  324. {
  325. dt.LoadDataRow(rows[i].ItemArray, true);
  326. }
  327. return dt;
  328. }
  329. /// <summary>
  330. /// 排序表的视图
  331. /// </summary>
  332. /// <param name="dt">原内存表</param>
  333. /// <param name="sorts">排序方式</param>
  334. /// <returns>排序后的内存表</returns>
  335. public static DataTable SortedTable(this DataTable dt, params string[] sorts)
  336. {
  337. if (dt.Rows.Count > 0)
  338. {
  339. string tmp = "";
  340. foreach (var t in sorts)
  341. {
  342. tmp += t + ",";
  343. }
  344. dt.DefaultView.Sort = tmp.TrimEnd(',');
  345. }
  346. return dt;
  347. }
  348. /// <summary>
  349. /// 根据条件过滤表的内容
  350. /// </summary>
  351. /// <param name="dt">原内存表</param>
  352. /// <param name="condition">过滤条件</param>
  353. /// <returns>过滤后的内存表</returns>
  354. public static DataTable FilterDataTable(this DataTable dt, string condition)
  355. {
  356. if (condition.Trim().Length == 0)
  357. {
  358. return dt;
  359. }
  360. var newdt = dt.Clone();
  361. DataRow[] dr = dt.Select(condition);
  362. dr.ForEach(t => newdt.ImportRow(t));
  363. return newdt;
  364. }
  365. }
  366. }