- ///
- /// DataTable数据集合返回实体
- ///
- [Serializable]
- public sealed class DataTableResponseEntity : IResponse
- {
- private readonly DataTable sourceTable;
- private readonly int PageCount;
- private readonly int totalCount;
- private readonly Dictionary<string, Tuple
string, Func<object, object>>> addValuePairs = new Dictionary<string, Tuplestring, Func<object, object>>>(); - private readonly Dictionary<string, string> removeValuePairs = new Dictionary<string, string>();
- private readonly Dictionary<string, Tuple
string, Func<object, object>>> editValuePairs = new Dictionary<string, Tuplestring, Func<object, object>>>(); -
- ///
- /// 构造函数
- ///
- 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<T>(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<T>(int rows, string fieldName, Func<object, T> 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<T>(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<T>(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<T>(DataRow dataRow, string fieldName, Func<object, DataColumn, T> 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<T>(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<string> 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<object, object> valueFrom)
- {
- return this.AddColumn(newColumnName, newColumnType, string.Empty, valueFrom);
- }
- ///
- /// 新增列
- ///
- ///
- public DataTableResponseEntity AddColumn(bool isAdd, string newColumnName, Type newColumnType, Func<object, object> valueFrom)
- {
- if (isAdd == false)
- return this;
- return this.AddColumn(newColumnName, newColumnType, string.Empty, valueFrom);
- }
- ///
- /// 新增列
- ///
- ///
- public DataTableResponseEntity AddColumn(string newColumnName, Type newColumnType, string originalColumnName, Func<object, object> 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<object, object> 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<string, Tuple<string, Type>> mayAddCols = editValuePairs.ToDictionary
string, Tuplestring, Func<object, object>>>, string, Tuple<string, Type>>(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());