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