實現DataTable按字段進行分類、按列數據匯總、序列化對象數組、所有字段轉小寫、動態對象數組、數據分頁
分類DataTableClassfiy實體:
/// <summary>/// 單個分類表/// </summary>public class DataTableClassfiy{/// <summary>/// 分類名稱/// </summary>public string Name { get; set; }/// <summary>/// 分類數據/// </summary>public DataTable Data { get; set; }/// <summary>/// 該類型數量/// </summary>public int Count { get; set; }}
DataTable 操作類:
/// <summary>/// DataTable擴展類,/// </summary>public static class DataTableEx{/// <summary>/// 通過指定字段對DataTable進行分類/// </summary>/// <param name="dt">需要分類的表格</param>/// <param name="field">需要進行分類的字段</param>/// <param name="isFilterNull">是否過濾空屬性</param>/// <param name="isHideData">是否賦值Data</param>/// <returns></returns>public static List<DataTableClassfiy> GetTableClassfiy(this DataTable dt, string field, bool isFilterNull = false, bool isHideData = false){List<DataTableClassfiy> tableClassfiys = new List<DataTableClassfiy>();DataView dv = new DataView(dt);DataTable dtTJ = dv.ToTable(true, field);//獲取該字段唯一值for (int i = 0; i < dtTJ.Rows.Count; i++){string value = dtTJ.Rows[i][field].ToString();if (isFilterNull && string.IsNullOrWhiteSpace(value)) continue;string express = string.Format("{0}='{1}'", field, value);var res = dt.Select(express);//按條件查詢出符合條件的行DataTable resDt = dt.Clone();//克隆一個表結構foreach (var j in res){resDt.ImportRow(j);//將符合條件的行放進新表}DataTableClassfiy tableClassfiy = new DataTableClassfiy(){Name = value,Data = !isHideData ? resDt : null,Count = resDt.Rows.Count};tableClassfiys.Add(tableClassfiy);}return tableClassfiys;}/// <summary>/// 通過指定列,返回數據匯總/// </summary>/// <param name="dt"></param>/// <param name="field"></param>/// <returns></returns>public static int GetSumByField(this DataTable dt, string field){var count = 0;for (int i = 0; i < dt.Rows.Count; i++){try{if (!(dt.Rows[i][field] is DBNull) && !string.IsNullOrWhiteSpace(dt.Rows[i][field].ToString())){Console.WriteLine(dt.Rows[i][field].ToString());count = count + int.Parse(dt.Rows[i][field].ToString());}}catch (Exception ex){Console.WriteLine(ex.Message);}}return count;}/// <summary>/// 返回DataTable的對象數組/// </summary>/// <typeparam name="T"></typeparam>/// <param name="dt"></param>/// <returns></returns>public static List<T> GetTableEntity<T>(this DataTable dt, bool isDesriptionAttribute = false){List<T> res = new List<T>();Type type = typeof(T);var pros = type.GetProperties();foreach (DataRow dr in dt.Rows){var ins = (T)Activator.CreateInstance(type);foreach (var pro in pros){string cName = pro.Name;if (isDesriptionAttribute is true){cName = ((DescriptionAttribute)(pro.GetCustomAttributes(typeof(DescriptionAttribute), false)[0])).Description;}if (dt.Columns.Contains(cName)){string dataType = pro.PropertyType.ToString().ToLower();if (dataType == "system.int32" || dataType == "system.double"){if (dr[cName] is DBNull){pro.SetValue(ins, 0);continue;}object value = 0;if (dataType == "system.int32"){value = int.Parse(dr[cName].ToString());}else if (dataType == "system.double"){value = double.Parse(dr[cName].ToString());}pro.SetValue(ins, value);continue;}pro.SetValue(ins, dr[cName] is DBNull ? null : dr[cName]);}}res.Add(ins);}return res;}/// <summary>/// 將Datatable所有字段轉小寫/// </summary>/// <param name="dt"></param>public static void GetColumnsLow(this DataTable dt){foreach (DataColumn dc in dt.Columns){dc.ColumnName = dc.ColumnName.ToLower();}}/// <summary>/// 獲取DataTable的動態對象--------------DynamicObject的dynamic不能用于接口返回/// </summary>/// <param name="table"></param>/// <returns></returns>public static List<dynamic> AsObjDynamicEnumerable(this DataTable table){return table.AsEnumerable().Select(row => new DynamicRow(row)).ToList<dynamic>();}/// <summary>/// 將DataTable 轉換成 List<dynamic>------------ExpandoObject的dynamic才可以用于接口返回/// reverse 反轉:控制返回結果中是只存在 FilterField 指定的字段,還是排除./// [flase 返回FilterField 指定的字段]|[true 返回結果剔除 FilterField 指定的字段]/// FilterField 字段過濾,FilterField 為空 忽略 reverse 參數;返回DataTable中的全部數/// </summary>/// <param name="table">DataTable</param>/// <param name="reverse">/// 反轉:控制返回結果中是只存在 FilterField 指定的字段,還是排除./// [flase 返回FilterField 指定的字段]|[true 返回結果剔除 FilterField 指定的字段]///</param>/// <param name="FilterField">字段過濾,FilterField 為空 忽略 reverse 參數;返回DataTable中的全部數據</param>/// <returns>List<dynamic></returns>public static List<dynamic> ToDbExObjnamicList(this DataTable table, bool reverse = true, params string[] FilterField){var modelList = new List<dynamic>();foreach (DataRow row in table.Rows){dynamic model = new ExpandoObject();var dict = (IDictionary<string, object>)model;foreach (DataColumn column in table.Columns){if (FilterField.Length != 0){if (reverse == true){if (!FilterField.Contains(column.ColumnName)){dict[column.ColumnName] = row[column];}}else{if (FilterField.Contains(column.ColumnName)){dict[column.ColumnName] = row[column];}}}else{dict[column.ColumnName] = row[column];}}modelList.Add(model);}return modelList;}/// <summary>/// DataRow 轉換成 dynamic------------ExpandoObject的dynamic才可以用于接口返回/// reverse 反轉:控制返回結果中是只存在 FilterField 指定的字段,還是排除./// [flase 返回FilterField 指定的字段]|[true 返回結果剔除 FilterField 指定的字段]/// FilterField 字段過濾,FilterField 為空 忽略 reverse 參數;返回DataTable中的全部數/// </summary>/// <param name="table">DataTable</param>/// <param name="reverse">/// 反轉:控制返回結果中是只存在 FilterField 指定的字段,還是排除./// [flase 返回FilterField 指定的字段]|[true 返回結果剔除 FilterField 指定的字段]///</param>/// <param name="FilterField">字段過濾,FilterField 為空 忽略 reverse 參數;返回DataRow中的全部數據</param>/// <returns>List<dynamic></returns>public static dynamic ToDbExObjnamic(this DataRow row, bool reverse = true, params string[] FilterField){dynamic model = new ExpandoObject();var dict = (IDictionary<string, object>)model;foreach (DataColumn column in row.Table.Columns){if (FilterField.Length != 0){if (reverse == true){if (!FilterField.Contains(column.ColumnName)){dict[column.ColumnName] = row[column] is DBNull ? null : row[column];}}else{if (FilterField.Contains(column.ColumnName)){dict[column.ColumnName] = row[column] is DBNull?null: row[column];}}}else{dict[column.ColumnName] = row[column] is DBNull ? null : row[column];}}return model;}/// <summary>/// DaTable截取/// </summary>/// <param name="dt"></param>/// <param name="beginRecord"></param>/// <param name="count"></param>/// <returns></returns>public static DataTable GetTablePageBreak(this DataTable dt,int beginRecord, int count){DataTable dtTemp = dt.Clone();int endRecord = beginRecord + count;if (endRecord > dt.Rows.Count) endRecord = dt.Rows.Count;for (int i = beginRecord; i < endRecord; i++){dtTemp.ImportRow(dt.Rows[i]);}return dtTemp;}#region Private-Methodprivate sealed class DynamicRow : DynamicObject{private readonly DataRow _row;internal DynamicRow(DataRow row) { _row = row; }public override bool TryGetMember(GetMemberBinder binder, out object result){var retVal = _row.Table.Columns.Contains(binder.Name);result = retVal ? _row[binder.Name] : null;return retVal;}}#endregion}