using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Linq; using System.Xml.Linq; namespace JiShe.CollectBus.Common.Extensions { public static class DataTableExtensions { /// Converts to list. /// /// The dt. /// ///
///
[Description("转换为列表")] public static IList ToList(this DataTable dt) where T : class { IList list = new List(); foreach (DataRow dr in dt.Rows) { T t = Activator.CreateInstance(); var props = typeof(T).GetProperties(); foreach (var pro in props) { var tempName = pro.Name; if (!dt.Columns.Contains(tempName)) continue; if (!pro.CanWrite) continue; var value = dr[tempName]; if (value != DBNull.Value) pro.SetValue(t, value, null); } list.Add(t); } return list; } /// Converts to data table. /// /// The source. /// ///
///
[Description("转换为DataTable")] public static DataTable ToDataTable(this ICollection source) { var props = typeof(T).GetProperties(); var dt = new DataTable(); dt.Columns.AddRange(props.Select(p => new DataColumn(p.Name, (p.PropertyType.IsGenericType) && (p.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) ? p.PropertyType.GetGenericArguments()[0] : p.PropertyType)).ToArray()); for (var i = 0; i < source.Count; i++) { var tempList = new ArrayList(); foreach (var obj in props.Select(pi => pi.GetValue(source.ElementAt(i), null))) tempList.Add(obj); var array = tempList.ToArray(); dt.LoadDataRow(array, true); } return dt; } /// Converts to xml. /// The dt. /// Name of the root. /// ///
///
[Description("转换为Xml")] public static XDocument ToXml(this DataTable dt, string rootName) { var xdoc = new XDocument { Declaration = new XDeclaration("1.0", "utf-8", "") }; xdoc.Add(new XElement(rootName)); foreach (DataRow row in dt.Rows) { var element = new XElement(dt.TableName); foreach (DataColumn col in dt.Columns) { element.Add(new XElement(col.ColumnName, row[col].ToString().Trim(' '))); } xdoc.Root?.Add(element); } return xdoc; } /// /// "SELECT DISTINCT" over a DataTable /// /// Input DataTable /// Field to select (distinct) /// [Description("在DataTable中'SELECT DISTINCT'")] public static DataTable SelectDistinct(this DataTable sourceTable, string fieldName) { return SelectDistinct(sourceTable, fieldName, string.Empty); } /// /// "SELECT DISTINCT" over a DataTable /// /// Input DataTable /// Fields to select (distinct) Split ',' /// Optional filter to be applied to the selection /// public static DataTable SelectDistinct(this DataTable sourceTable, string fieldNames, string filter) { var dt = new DataTable(); var arrFieldNames = fieldNames.Replace(" ", "").Split(','); foreach (var s in arrFieldNames) { if (sourceTable.Columns.Contains(s)) dt.Columns.Add(s, sourceTable.Columns[s].DataType); else throw new Exception($"The column {s} does not exist."); } object[] lastValues = null; foreach (DataRow dr in sourceTable.Select(filter, fieldNames)) { var newValues = GetRowFields(dr, arrFieldNames); if (lastValues == null || !(ObjectComparison(lastValues, newValues))) { lastValues = newValues; dt.Rows.Add(lastValues); } } return dt; } /// Selects the rows. /// The dt. /// The where expression. /// The order by expression. /// ///
///
[Description("查询全部行")] public static DataTable SelectRows(this DataTable dt, string whereExpression, string orderByExpression) { dt.DefaultView.RowFilter = whereExpression; dt.DefaultView.Sort = orderByExpression; return dt.DefaultView.ToTable(); } /// take any DataTable and remove duplicate rows based on any column. /// The dt. /// Name of the key col. /// ///
///
[Description("删除重复的行")] public static DataTable Duplicate(this DataTable dt, string keyColName) { var tblOut = dt.Clone(); foreach (DataRow row in dt.Rows) { var found = false; var caseIdToTest = row[keyColName].ToString(); foreach (DataRow row2 in tblOut.Rows) { if (row2[keyColName].ToString() == caseIdToTest) { found = true; break; } } if (!found) tblOut.ImportRow(row); } return tblOut; } /// Checks if two DataTable objects have the same content. /// The this data table. /// The other data table. /// ///
///
[Description("检查两个DataTable对象是否具有相同的内容")] public static bool EqualsByContent(this DataTable thisDataTable, DataTable otherDataTable) { // Compare row count. if (thisDataTable.Rows.Count != otherDataTable.Rows.Count) { return false; } // Compare column count. if (thisDataTable.Columns.Count != otherDataTable.Columns.Count) { return false; } // Compare data in each cell of each row. for (int i = 0; i < thisDataTable.Rows.Count; i++) { for (int j = 0; j < thisDataTable.Columns.Count; j++) { if (!thisDataTable.Rows[i][j].Equals(otherDataTable.Rows[i][j])) { return false; } } } // The two DataTables contain the same data. return true; } /// Renames the column. /// The dt. /// The old name. /// The new name. [Description("重命名列")] public static void RenameColumn(this DataTable dt, string oldName, string newName) { if (dt != null && !string.IsNullOrEmpty(oldName) && !string.IsNullOrEmpty(newName) && oldName != newName) { int idx = dt.Columns.IndexOf(oldName); dt.Columns[idx].ColumnName = newName; dt.AcceptChanges(); } } /// Removes the column. /// The dt. /// Name of the column. [Description("删除列")] public static void RemoveColumn(this DataTable dt, string columnName) { if (dt != null && !string.IsNullOrEmpty(columnName) && dt.Columns.IndexOf(columnName) >= 0) { int idx = dt.Columns.IndexOf(columnName); dt.Columns.RemoveAt(idx); dt.AcceptChanges(); } } private static object[] GetRowFields(DataRow dr, string[] arrFieldNames) { if (arrFieldNames.Length == 1) return new object[] { dr[arrFieldNames[0]] }; var itemArray = new ArrayList(); foreach (var field in arrFieldNames) itemArray.Add(dr[field]); return itemArray.ToArray(); } private static bool ObjectComparison(object a, object b) { if (a == DBNull.Value && b == DBNull.Value) // both are DBNull.Value return true; if (a == DBNull.Value || b == DBNull.Value) // only one is DBNull.Value return false; return a.Equals(b); // value type standard comparison } private static bool ObjectComparison(IReadOnlyList a, IReadOnlyList b) { var retValue = true; if (a.Count == b.Count) for (var i = 0; i < a.Count; i++) { if (!ObjectComparison(a[i], b[i])) { retValue = false; break; } retValue = true; } return retValue; } } }