///
/// DataTable数据集合返回实体
///
[Serializable]
public sealed class DataTableResponseEntity : IResponse
{
private readonly DataTable sourceTable;
private readonly int PageCount;
private readonly int totalCount;
private readonly Dictionary>> addValuePairs = new Dictionary>>();
private readonly Dictionary removeValuePairs = new Dictionary();
private readonly Dictionary>> editValuePairs = new Dictionary>>();
///
/// 构造函数
///
public DataTableResponseEntity(DataTable dataTable)
: this(dataTable, dataTable.Rows.Count)
{
}
///
/// 构造函数
///
public DataTableResponseEntity(DataTable dataTable, int totalCount)
{
this.sourceTable = dataTable;
this.PageCount = dataTable.Rows.Count;
this.totalCount = totalCount;
}
///
/// 获取总数
///
public int TotalCount { get { return this.totalCount; } }
///
/// 是否包含行
///
public bool HasRows
{
get { return this.PageCount > 0; }
}
///
///
///
public int RowsCount { get { return this.sourceTable.Rows.Count; } }
///
/// 获取字段的值
///
///
public T SafeRead(int rows, string fieldName)
{
if (rows < 0 || rows > this.PageCount)
return default;
var dataRow = this.sourceTable.Rows[rows];
if (this.sourceTable.Columns.Contains(fieldName) == false || Convert.IsDBNull(dataRow[fieldName]))
return default;
if (this.sourceTable.Columns[fieldName].DataType != typeof(T))
return (T)Convert.ChangeType(dataRow[fieldName], typeof(T));
return dataRow.Field(fieldName);
}
///
/// 获取字段的值
///
///
public T SafeRead(int rows, string fieldName, Func funValue)
{
if (rows < 0 || rows > this.PageCount)
return default;
var dataRow = this.sourceTable.Rows[rows];
if (this.sourceTable.Columns.Contains(fieldName) == false || Convert.IsDBNull(dataRow[fieldName]))
return funValue.Invoke(null);
if (this.sourceTable.Columns[fieldName].DataType != typeof(T))
return funValue.Invoke(dataRow[fieldName]);
return funValue.Invoke(dataRow.Field(fieldName));
}
///
/// 获取字段的值
///
///
public void SafeWrite(int rows, string fieldName, T writeValue, bool isThrow = false)
{
if (rows < 0 || rows > this.PageCount)
return;
var dataRow = this.sourceTable.Rows[rows];
if (this.sourceTable.Columns.Contains(fieldName) == false)
{
if (isThrow)
return;
this.sourceTable.Columns.Add(fieldName, typeof(T));
dataRow.SetField(fieldName, writeValue);
return;
}
if (this.sourceTable.Columns[fieldName].DataType != typeof(T))
{
object newValue = Convert.ChangeType(writeValue, this.sourceTable.Columns[fieldName].DataType);
dataRow[fieldName] = newValue;
return;
}
dataRow.SetField(fieldName, writeValue);
}
///
/// 获取字段的值
///
///
public T SafeRead(int rows, string fieldName, T defualtValue)
{
if (rows < 0 || rows > this.PageCount)
return default;
var dataRow = this.sourceTable.Rows[rows];
if (this.sourceTable.Columns.Contains(fieldName) == false || Convert.IsDBNull(dataRow[fieldName]))
return defualtValue;
if (this.sourceTable.Columns[fieldName].DataType != typeof(T))
return defualtValue;
return dataRow.Field(fieldName);
}
///
/// 获取字段的值
///
///
public T SafeRead(DataRow dataRow, string fieldName, Func funValue)
{
if (this.sourceTable.Columns.Contains(fieldName) == false || Convert.IsDBNull(dataRow[fieldName]))
return funValue.Invoke(null, null);
if (this.sourceTable.Columns[fieldName].DataType != typeof(T))
return funValue.Invoke(dataRow[fieldName], this.sourceTable.Columns[fieldName]);
return funValue.Invoke(dataRow.Field(fieldName), this.sourceTable.Columns[fieldName]);
}
///
///
///
///
///
public T DoWhile(Func ExecuteTask)
{
return ExecuteTask.Invoke(this);
}
///
///
///
///
public EnumerableRowCollection AsEnumerable()
{
return this.sourceTable.AsEnumerable();
}
private bool ColumnEqual(object objectA, object objectB)
{
if (objectA == DBNull.Value && objectB == DBNull.Value)
return true;
if (objectA == DBNull.Value || objectB == DBNull.Value)
return false;
return (objectA.Equals(objectB));
}
private bool RowEqual(DataRow rowA, DataRow rowB, DataColumnCollection columns)
{
bool result = true;
for (int i = 0; i < columns.Count; i++)
result &= ColumnEqual(rowA[columns[i].ColumnName], rowB[columns[i].ColumnName]);
return result;
}
///
/// 按照fieldName从sourceTable中选择出不重复的行,
/// 相当于select distinct fieldName1,fieldName2,,fieldNamen from sourceTable
///
///
/// 列名数组
/// 一个新的不含重复行的DataTable,列只包括fieldNames中指明的列
public DataTableResponseEntity Split(string filterExpression, string[] fieldNames = null)
{
DataTable resultTable = new DataTable();
foreach (var field in fieldNames)
{
if (string.IsNullOrEmpty(field) || resultTable.Columns.Contains(field))
continue;
resultTable.Columns.Add(field, this.sourceTable.Columns[field].DataType);
}
object[] values = new object[fieldNames.Length];
DataRow lastRow = null;
foreach (DataRow dr in this.sourceTable.Select(filterExpression, string.Empty))
{
if (lastRow == null || !(RowEqual(lastRow, dr, resultTable.Columns)))
{
lastRow = dr;
for (int i = 0; i < fieldNames.Length; i++)
values[i] = dr[fieldNames[i]];
resultTable.Rows.Add(values);
}
}
return new DataTableResponseEntity(resultTable);
}
///
///
///
///
public DataTable AsTable()
{
RemoveTableColumn();
AddTableColumn();
EditTableColumn();
return this.sourceTable;
}
///
///
///
///
public string AsTableJson()
{
return JsonConvert.SerializeObject(this.sourceTable);
}
///
/// 获取列名称
///
public IEnumerable Columns
{
get
{
foreach (DataColumn dc in this.sourceTable.Columns)
yield return dc.ColumnName;
}
}
///
/// 获取列
///
public IEnumerable DataColumns
{
get
{
foreach (DataColumn dc in this.sourceTable.Columns)
yield return dc;
}
}
///
/// 新增列
///
///
public DataTableResponseEntity AddColumn(string newColumnName, Type newColumnType, object newColumnValue)
{
return this.AddColumn(newColumnName, newColumnType, string.Empty, (originalValue) => newColumnValue);
}
///
/// 新增列
///
///
public DataTableResponseEntity AddColumn(string newColumnName, Type newColumnType, Func valueFrom)
{
return this.AddColumn(newColumnName, newColumnType, string.Empty, valueFrom);
}
///
/// 新增列
///
///
public DataTableResponseEntity AddColumn(bool isAdd, string newColumnName, Type newColumnType, Func valueFrom)
{
if (isAdd == false)
return this;
return this.AddColumn(newColumnName, newColumnType, string.Empty, valueFrom);
}
///
/// 新增列
///
///
public DataTableResponseEntity AddColumn(string newColumnName, Type newColumnType, string originalColumnName, Func valueFrom)
{
this.addValuePairs.TryAdd(newColumnName, Tuple.Create(newColumnType, originalColumnName, valueFrom));
return this;
}
///
/// 新增字段
///
private void AddTableColumn()
{
if (this.sourceTable == null || this.sourceTable.Rows.Count <= 0 || addValuePairs == null || addValuePairs.Count <= 0)
return;
foreach (var newCol in addValuePairs)
{
if (this.sourceTable.Columns.Contains(newCol.Key))
continue;
if (newCol.Value.Item1 != null)
this.sourceTable.Columns.Add(newCol.Key, newCol.Value.Item1);
else
this.sourceTable.Columns.Add(newCol.Key);
}
foreach (DataRow currentRow in this.sourceTable.Rows)
{
foreach (var newCol in addValuePairs)
{
var newValue = newCol.Value.Item3?.Invoke(!string.IsNullOrEmpty(newCol.Value.Item2) ? currentRow[newCol.Value.Item2] : null);
currentRow.SetField(newCol.Key, newValue);
}
}
}
///
/// 删除列
///
///
public DataTableResponseEntity RemoveColumn(string newColumnName)
{
this.removeValuePairs.TryAdd(newColumnName, newColumnName);
return this;
}
///
/// 删除字段
///
private void RemoveTableColumn()
{
if (this.sourceTable == null || this.sourceTable.Rows.Count <= 0 || this.removeValuePairs == null || this.removeValuePairs.Count <= 0)
return;
foreach (var newCol in removeValuePairs)
{
if (this.sourceTable.Columns.Contains(newCol.Key))
this.sourceTable.Columns.Remove(newCol.Key);
}
}
///
/// 修改列
///
///
public DataTableResponseEntity EditColumn(string newColumnName, Type newColumnType, string originalColumnName, Func valueFrom = null)
{
this.editValuePairs.TryAdd(newColumnName, Tuple.Create(newColumnType, originalColumnName, valueFrom));
return this;
}
///
/// 修改字段
///
private void EditTableColumn()
{
if (this.sourceTable == null || this.sourceTable.Rows.Count <= 0 || this.editValuePairs == null || this.editValuePairs.Count <= 0)
return;
//新增需要的 Where(t => this.currentTable.Columns[t.Value.Item2].DataType != t.Value.Item1)
Dictionary> mayAddCols = editValuePairs.ToDictionary>>, string, Tuple>(keySelector: (keyPairItem) => keyPairItem.Key, elementSelector: (keyPairItem) => Tuple.Create(keyPairItem.Value.Item2, keyPairItem.Value.Item1));
//editValuePairs KEY:新字段,Value:新类型,旧字段,值转换Func
//mayAddCols KEY:新字段,Value:旧字段,新类型
foreach (var ss in mayAddCols)
{
if (!this.sourceTable.Columns.Contains(ss.Key))
this.sourceTable.Columns.Add(ss.Key, ss.Value.Item2);
foreach (DataRow currentRow in this.sourceTable.Rows)
{
var newValue = currentRow[ss.Value.Item1];
var editValue = editValuePairs.FirstOrDefault(y => y.Key == ss.Key);
if (!string.IsNullOrEmpty(editValue.Key) && editValue.Value.Item3 != null)
newValue = editValue.Value.Item3.Invoke(newValue);
//设置到新列上
currentRow.SetField(ss.Key, newValue);
}
}
//避免多个新字段 取到同个旧字段的值
foreach (var ss in mayAddCols)
{
if (this.sourceTable.Columns.Contains(ss.Value.Item1) && !ss.Value.Item1.Equals(ss.Key, StringComparison.OrdinalIgnoreCase))
this.sourceTable.Columns.Remove(ss.Value.Item1);
}
}
}
使用:
var currTable = dataTableResponseEntity
.EditColumn("RowNo", typeof(Int64), "FSEQ", t => t)
.EditColumn("MaterialCode", typeof(string), "FItemNumber", t => t.ToString())
.EditColumn("Qty", typeof(decimal), "FQTY", t => t)
.EditColumn("ErpId", typeof(string), "FID", t => t.ToString())
.EditColumn("ErpSubId", typeof(string), "FEntryID", t => t.ToString());