using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Xml;
using System.IO;
using System.Data.Common;
using System.ComponentModel;
using CYQ.Data.UI;
using CYQ.Data.Cache;
using CYQ.Data.SQL;
using CYQ.Data.Tool;
using System.Collections.Specialized;
using System.Web;
namespace CYQ.Data.Table
{
///
/// 表格
///
public partial class MDataTable
{
#region 隐式转换
///
/// 从DataReader隐式转换成MDataTable
///
public static implicit operator MDataTable(DbDataReader sdr)
{
MDataTable dt = CreateFrom(sdr);
if (sdr != null)
{
sdr.Close();
sdr.Dispose();
sdr = null;
}
return dt;
}
///
/// 从DataTable隐式转换成MDataTable
///
public static implicit operator MDataTable(DataTable dt)
{
if (dt == null)
{
return null;
}
MDataTable mdt = new MDataTable(dt.TableName);
if (dt.Columns != null && dt.Columns.Count > 0)
{
foreach (DataColumn item in dt.Columns)
{
mdt.Columns.Add(new MCellStruct(item.ColumnName, DataType.GetSqlType(item.DataType), item.ReadOnly, item.AllowDBNull, item.MaxLength));
}
foreach (DataRow row in dt.Rows)
{
MDataRow mdr = mdt.NewRow();
for (int i = 0; i < dt.Columns.Count; i++)
{
mdr[i].Value = row[i];
}
mdt.Rows.Add(mdr, row.RowState != DataRowState.Modified);
}
}
return mdt;
}
///
/// 从行集合隐式转换成MDataTable
///
///
///
public static implicit operator MDataTable(List rows)
{
return (MDataRowCollection)rows;
}
///
/// 将一行数据装载成一个表。
///
///
public static implicit operator MDataTable(MDataRow row)
{
MDataTable mTable = new MDataTable(row.TableName);
mTable.Conn = row.Conn;
mTable.LoadRow(row);
return mTable;
}
///
/// 将一行数据装载成一个表。
///
///
public static implicit operator MDataTable(MDataRowCollection rows)
{
if (rows == null || rows.Count == 0)
{
return null;
}
MDataTable mdt = new MDataTable(rows[0].TableName);
mdt.Conn = rows[0].Conn;
mdt.Columns = rows[0].Columns;
mdt.Rows.AddRange(rows);
return mdt;
}
#endregion
#region 属性
private MDataRowCollection _Rows;
///
/// 表格行
///
public MDataRowCollection Rows
{
get
{
return _Rows;
}
}
[NonSerialized]
private object _DynamicData;
///
/// 动态存储数据
///
public object DynamicData
{
get { return _DynamicData; }
set { _DynamicData = value; }
}
public MDataTable()
{
Init("default", null);
}
public MDataTable(string tableName)
{
Init(tableName, null);
}
public MDataTable(string tableName, MDataColumn mdc)
{
Init(tableName, mdc);
}
private void Init(string tableName, MDataColumn mdc)
{
_Rows = new MDataRowCollection(this);
_TableName = tableName;
if (_Columns == null)
{
_Columns = new MDataColumn(this);
if (mdc != null)
{
_Columns.AddRange(mdc);
}
}
}
private string _TableName = string.Empty;
///
/// 表名
///
public string TableName
{
get
{
return _TableName;
}
set
{
_TableName = value;
}
}
private string _Description = string.Empty;
///
/// 表名描述
///
public string Description
{
get
{
if (string.IsNullOrEmpty(_Description))
{
_Description = TableSchema.GetTableDescription(Conn, _TableName);
if (string.IsNullOrEmpty(_Description))
{
_Description = _TableName;
}
}
return _Description;
}
set
{
_Description = value;
}
}
private MDataColumn _Columns;
///
/// 表格的架构列
///
public MDataColumn Columns
{
get
{
return _Columns;
}
set
{
_Columns = value;
_Columns._Table = this;
}
}
private string _Conn;
///
/// 该表归属的数据库链接。
///
public string Conn
{
get
{
if (string.IsNullOrEmpty(_Conn))
{
return AppConfig.DB.DefaultConn;
}
return _Conn;
}
set
{
_Conn = value;
}
}
#endregion
#region 方法
///
/// 新建一行
///
///
public MDataRow NewRow()
{
return NewRow(false);
}
///
/// 新建一行
///
/// 是否顺带添加到表中
///
public MDataRow NewRow(bool isAddToTable)
{
MDataRow mdr = new MDataRow(this);
if (isAddToTable)
{
Rows.Add(mdr, false);
}
return mdr;
}
#region 准备新开始的方法
///
/// 使用本查询,得到克隆后的数据
///
public MDataTable Select(object where)
{
return Select(0, 0, where);
}
///
/// 使用本查询,得到克隆后的数据
///
public MDataTable Select(int topN, object where)
{
return Select(1, topN, where);
}
///
/// 使用本查询,得到克隆后的数据
///
public MDataTable Select(int pageIndex, int pageSize, object where, params object[] selectColumns)
{
return MDataTableFilter.Select(this, pageIndex, pageSize, where, selectColumns);
}
///
/// 使用本查询,得到原数据的引用。
///
public MDataRow FindRow(object where)
{
return MDataTableFilter.FindRow(this, where);
}
///
/// 使用本查询,得到原数据的引用。
///
public MDataRowCollection FindAll(object where)
{
return MDataTableFilter.FindAll(this, where);
}
///
/// 统计满足条件的行所在的索引
///
public int GetIndex(object where)
{
return MDataTableFilter.GetIndex(this, where);
}
///
/// 统计满足条件的行数
///
public int GetCount(object where)
{
return MDataTableFilter.GetCount(this, where);
}
///
/// 根据条件分拆成两个表【满足条件,和非满足条件的】,分出来的数据行和原始表仍是同一个引用
///
public MDataTable[] Split(object where)
{
return MDataTableFilter.Split(this, where);
}
#endregion
///
/// 加载行(包括行架构)[提示,仅当表为空架构时有效]
///
///
internal void LoadRow(MDataRow row) //是否直接能用Row.Table呢??、
{
if (this.Columns.Count == 0 && row != null && row.Count > 0)
{
this.Columns = row.Columns.Clone();
if (!string.IsNullOrEmpty(_TableName) && _TableName.StartsWith("SysDefault"))
{
_TableName = row.TableName;
}
_Conn = row.Conn;
if (!row[0].IsNullOrEmpty)
{
NewRow(true).LoadFrom(row);
//_Rows.Add(row);
}
}
}
///
/// 转换成DataTable
///
public DataTable ToDataTable()
{
DataTable dt = new DataTable(_TableName);
if (Columns != null && Columns.Count > 0)
{
bool checkDuplicate = Columns.CheckDuplicate;
List duplicateName = new List();
for (int j = 0; j < Columns.Count; j++)
{
MCellStruct item = Columns[j];
if (string.IsNullOrEmpty(item.ColumnName))
{
item.ColumnName = "Empty_" + item;
}
if (!checkDuplicate && dt.Columns.Contains(item.ColumnName))//去重。
{
string rndName = Guid.NewGuid().ToString();
dt.Columns.Add(rndName, item.ValueType);
duplicateName.Add(rndName);
continue;
}
dt.Columns.Add(item.ColumnName, item.ValueType);
}
int count = dt.Columns.Count;
foreach (MDataRow row in Rows)
{
DataRow dr = dt.NewRow();
for (int i = 0; i < count; i++)
{
if (row[i].IsNull)
{
dr[i] = DBNull.Value;
}
else
{
dr[i] = row[i].Value;
}
}
dt.Rows.Add(dr);
}
for (int i = 0; i < duplicateName.Count; i++)
{
dt.Columns.Remove(duplicateName[i]);
}
}
dt.AcceptChanges();
return dt;
}
///
/// 输出Xml文档
///
public string ToXml()
{
return ToXml(false);
}
public string ToXml(bool isConvertNameToLower)
{
return ToXml(isConvertNameToLower, true, true);
}
///
/// 输出Xml文档
///
/// 名称转小写
///
public string ToXml(bool isConvertNameToLower, bool needHeader, bool needRootNode)
{
StringBuilder xml = new StringBuilder();
if (Columns.Count > 0)
{
string tableName = string.IsNullOrEmpty(_TableName) ? "Root" : _TableName;
string rowName = string.IsNullOrEmpty(_TableName) ? "Row" : _TableName;
if (isConvertNameToLower)
{
tableName = tableName.ToLower();
rowName = rowName.ToLower();
}
if (needHeader)
{
xml.Append("");
}
if (needRootNode)
{
xml.AppendFormat("\r\n<{0}>", tableName);
}
foreach (MDataRow row in Rows)
{
xml.AppendFormat("\r\n <{0}>", rowName);
foreach (MDataCell cell in row)
{
xml.Append(cell.ToXml(isConvertNameToLower));
}
xml.AppendFormat("\r\n {0}>", rowName);
}
if (needRootNode)
{
xml.AppendFormat("\r\n{0}>", tableName);
}
}
return xml.ToString();
}
public bool WriteXml(string fileName)
{
return WriteXml(fileName, false);
}
///
/// 保存Xml
///
public bool WriteXml(string fileName, bool isConvertNameToLower)
{
return IOHelper.Write(fileName, ToXml(isConvertNameToLower), Encoding.UTF8);
}
///
/// 输出Json
///
public string ToJson()
{
return ToJson(true);
}
public string ToJson(bool addHead)
{
return ToJson(addHead, false);
}
/// 输出头部信息[带count、Success、ErrorMsg](默认true)
/// 首行输出表架构信息,反接收时可还原架构(默认false)
public string ToJson(bool addHead, bool addSchema)
{
return ToJson(addHead, addSchema, RowOp.None);
}
/// 过滤选项
public string ToJson(bool addHead, bool addSchema, RowOp rowOp)
{
return ToJson(addHead, addSchema, rowOp, false);
}
public string ToJson(bool addHead, bool addSchema, RowOp rowOp, bool isConvertNameToLower)
{
return ToJson(addHead, addSchema, rowOp, isConvertNameToLower, JsonHelper.DefaultEscape);
}
/// 符号转义选项
public string ToJson(bool addHead, bool addSchema, RowOp rowOp, bool isConvertNameToLower, EscapeOp escapeOp)
{
JsonHelper helper = new JsonHelper(addHead, addSchema);
helper.Escape = escapeOp;
helper.IsConvertNameToLower = isConvertNameToLower;
helper.RowOp = rowOp;
helper.Fill(this);
bool checkArrayEnd = !addHead && !addSchema;
return helper.ToString(checkArrayEnd);
}
///
/// 输出Json[可指定保存路径]
///
public bool WriteJson(bool addHead, bool addSchema, string fileName)
{
return IOHelper.Write(fileName, ToJson(addHead, addSchema));
}
///
/// 将数据表绑定到列表控件
///
/// 列表控件[包括Repeater/DataList/GridView/DataGrid等]
public void Bind(object control)
{
Bind(control, null);
}
///
/// 将数据表绑定到列表控件
///
/// 列表控件[包括Repeater/DataList/GridView/DataGrid等]
/// 当Control为XHtmlAction对象时,需要指定绑定的节点ID
public void Bind(object control, string nodeID)
{
MBindUI.Bind(control, this, nodeID);
}
///
/// 将新表的行放到原表的下面。
///
///
public void Merge(MDataTable newTable)
{
if (newTable != null && newTable.Rows.Count > 0)
{
int count = newTable.Rows.Count;//提前获取总数,是为了避免dt.Merge(dt);//加载自身导致的死循环。
for (int i = 0; i < count; i++)
{
// _Rows.Add(newTable.Rows[i]);
NewRow(true).LoadFrom(newTable.Rows[i]);
}
}
}
///
/// 将表里所有行的数据行的状态全部重置
///
/// 状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]]
public MDataTable SetState(int state)
{
SetState(state, BreakOp.None); return this;
}
///
/// 将表里所有行的数据行的状态全部重置
///
/// 状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]]
/// 状态设置选项
public MDataTable SetState(int state, BreakOp op)
{
if (Rows != null && Rows.Count > 0)
{
foreach (MDataRow row in Rows)
{
row.SetState(state, op);
}
}
return this;
}
///
/// 转实体列表
///
/// 是否使用Emit方式转换[数据越多[大于500条]性能越高],不写默认自适应判断
///
///
public List ToList(params bool[] useEmit)
{
List list = new List();
if (Rows != null && Rows.Count > 0)
{
if (((Rows.Count > 500 && useEmit.Length == 0) || (useEmit.Length > 0 && useEmit[0])) && typeof(T).BaseType.Name != "OrmBase")//远程代理实体的属性会变,无法用Emit
{
FastToT.EmitHandle emit = FastToT.Create(this);
foreach (MDataRow row in Rows)
{
list.Add(emit(row));
}
}
else
{
foreach (MDataRow row in Rows)
{
list.Add(row.ToEntity());
}
}
}
return list;
}
internal object ToList(Type t)
{
object listObj = Activator.CreateInstance(t);//创建实例
if (Rows != null && Rows.Count > 0)
{
Type[] paraTypeList = null;
Type listObjType=listObj.GetType();
StaticTool.GetArgumentLength(ref listObjType, out paraTypeList);
MethodInfo method = listObjType.GetMethod("Add");
foreach (MDataRow row in Rows)
{
method.Invoke(listObj, new object[] { row.ToEntity(paraTypeList[0]) });
}
}
return listObj;
}
///
/// 批量插入或更新 [提示:操作和当前表名有关,如当前表名不是要提交入库的表名,请给TableName属性重新赋值]
///
/// 操作选项[插入|更新]
public bool AcceptChanges(AcceptOp op)
{
return AcceptChanges(op, string.Empty);
}
/// 操作选项[插入|更新]
/// 指定新的数据库链接
/// AcceptOp为Update或Auto时,若需要设置联合主键为唯一检测或更新条件,则可设置多个字段名
public bool AcceptChanges(AcceptOp op, string newConn, params object[] jointPrimaryKeys)
{
bool result = false;
if (Columns.Count == 0 || Rows.Count == 0)
{
return false;//木有可更新的。
}
MDataTableBatchAction action = new MDataTableBatchAction(this, newConn);
if ((op & AcceptOp.Truncate) != 0)
{
action.IsTruncate = true;
op = (AcceptOp)(op - AcceptOp.Truncate);
}
action.SetJoinPrimaryKeys(jointPrimaryKeys);
switch (op)
{
case AcceptOp.Insert:
result = action.Insert(false);
break;
case AcceptOp.InsertWithID:
result = action.Insert(true);
break;
case AcceptOp.Update:
result = action.Update();
break;
case AcceptOp.Delete:
result = action.Delete();
break;
case AcceptOp.Auto:
result = action.Auto();
break;
}
if (result && AppConfig.Cache.IsAutoCache)
{
//取消AOP缓存。
AutoCache.ReadyForRemove(AutoCache.GetBaseKey(action.dalTypeTo, action.database, TableName));
}
return result;
}
///
/// 获取修改过的数据
///
///
public MDataTable GetChanges()
{
return GetChanges(RowOp.Update);
}
///
/// 获取修改过的数据(若无修改,则返回Null)
///
/// 仅Insert和Update选项可用
///
public MDataTable GetChanges(RowOp rowOp)
{
MDataTable dt = new MDataTable(_TableName);
dt.Columns = Columns;
dt.Conn = Conn;
dt.DynamicData = DynamicData;
dt.joinOnIndex = joinOnIndex;
dt.JoinOnName = dt.JoinOnName;
dt.RecordsAffected = RecordsAffected;
if (this.Rows.Count > 0)
{
if (rowOp == RowOp.Insert || rowOp == RowOp.Update)
{
int stateValue = (int)rowOp;
foreach (MDataRow row in Rows)
{
if (row.GetState() >= stateValue)
{
dt.Rows.Add(row, false);
}
}
}
}
return dt;
}
///
/// 返回某列的集合
/// 列名
///
public List GetColumnItems(string columnName)
{
return GetColumnItems(columnName, BreakOp.None, false);
}
///
/// 返回某列的集合
/// 列名
/// 参数选项
///
public List GetColumnItems(string columnName, BreakOp op)
{
return GetColumnItems(columnName, op, false);
}
///
/// 返回某列的集合
///
/// 列的类型
/// 列名
/// 过滤选项
/// 是否去掉重复数据
public List GetColumnItems(string columnName, BreakOp op, bool isDistinct)
{
int index = -1;
if (Columns != null)
{
index = Columns.GetIndex(columnName);
}
return GetColumnItems(index, op, isDistinct);
}
///
/// 返回某列的集合
///
/// 列的类型
/// 第N列
public List GetColumnItems(int columnIndex)
{
return GetColumnItems(columnIndex, BreakOp.None);
}
///
/// 返回某列的集合
///
/// 列的类型
/// 第N列
/// 过滤选项
///
public List GetColumnItems(int columnIndex, BreakOp op)
{
return GetColumnItems(columnIndex, op, false);
}
///
/// 返回某列的集合
///
/// 列的类型
/// 第N列
/// 过滤选项
/// 是否去掉重复数据
public List GetColumnItems(int columnIndex, BreakOp op, bool isDistinct)
{
List items = new List();
if (Columns != null && Rows != null && Rows.Count > 0)
{
if (columnIndex > -1)
{
MDataCell cell;
foreach (MDataRow row in Rows)
{
cell = row[columnIndex];
switch (op)
{
case BreakOp.Null:
if (cell.IsNull)
{
continue;
}
break;
case BreakOp.Empty:
if (cell.StringValue == "")
{
continue;
}
break;
case BreakOp.NullOrEmpty:
if (cell.IsNullOrEmpty)
{
continue;
}
break;
}
T value = row.Get(columnIndex, default(T));
if (!isDistinct || !items.Contains(value))
{
items.Add(value);
}
}
}
else
{
Error.Throw(string.Format("Table {0} can not find the column", TableName));
}
}
return items;
}
///
/// 复制表
///
public MDataTable Clone()
{
MDataTable newTable = GetSchema(true);
newTable.Conn = Conn;
newTable.DynamicData = DynamicData;
newTable.RecordsAffected = RecordsAffected;
newTable.TableName = TableName;
if (_Rows.Count > 0)
{
foreach (MDataRow oldRow in _Rows)
{
MDataRow newRow = newTable.NewRow();
newRow.LoadFrom(oldRow);
newTable.Rows.Add(newRow, false);
}
}
return newTable;
}
///
/// 复制表的结构
///
/// 是否克隆表结构
///
public MDataTable GetSchema(bool clone)
{
MDataTable newTable = new MDataTable(_TableName);
if (Columns.Count > 0)
{
newTable.Columns = clone ? Columns.Clone() : Columns;
}
newTable.Conn = Conn;
return newTable;
}
///
/// 过滤掉重复的数据行(仅比较基础类型、复杂数据类型仅比较类型名称)。
/// 被过滤的数据集表
///
public void Distinct(out MDataTable filterRows)
{
filterRows = null;
if (Rows.Count > 0)
{
List rowList = new List();
int cCount = Columns.Count;
for (int i = 0; i < Rows.Count; i++)
{
for (int j = Rows.Count - 1; j >= 0 && j != i; j--)//反序检测。
{
int eqCount = 0;
for (int k = 0; k < cCount; k++)//比较列
{
if (Rows[i][k].StringValue == Rows[j][k].StringValue)
{
eqCount++;
}
else
{
break;
}
}
if (eqCount == cCount)
{
rowList.Add(Rows[j]);
Rows.RemoveAt(j);
}
}
}
if (rowList.Count > 0)
{
filterRows = rowList;
}
}
}
///
/// 过滤掉重复的数据行(仅比较基础类型、复杂数据类型仅比较类型名称)。
///
public void Distinct()
{
MDataTable filterRows;
Distinct(out filterRows);
filterRows = null;
}
#endregion
public override string ToString()
{
return TableName;
}
}
public partial class MDataTable : IDataReader, IEnumerable//, IEnumerator
{
private int _Ptr = -1;//行索引
#region IDataRecord 成员
///
/// 获取列的总数
///
int IDataRecord.FieldCount
{
get
{
if (Columns != null)
{
return Columns.Count;
}
return 0;
}
}
bool IDataRecord.GetBoolean(int i)
{
return (bool)_Rows[_Ptr][i].Value;
}
byte IDataRecord.GetByte(int i)
{
return (byte)_Rows[_Ptr][i].Value;
}
long IDataRecord.GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
{
return (byte)_Rows[_Ptr][i].Value;
}
char IDataRecord.GetChar(int i)
{
return (char)_Rows[_Ptr][i].Value;
}
long IDataRecord.GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
{
return (char)_Rows[_Ptr][i].Value;
}
IDataReader IDataRecord.GetData(int i)
{
return this;
}
string IDataRecord.GetDataTypeName(int i)
{
return "";//绑定的可以不需要返回
//return DataType.GetDbType(Columns[i].SqlType.ToString()).ToString();
}
DateTime IDataRecord.GetDateTime(int i)
{
return (DateTime)_Rows[_Ptr][i].Value;
}
decimal IDataRecord.GetDecimal(int i)
{
return (decimal)_Rows[_Ptr][i].Value;
}
double IDataRecord.GetDouble(int i)
{
return (double)_Rows[_Ptr][i].Value;
}
Type IDataRecord.GetFieldType(int i)
{
return _Columns[i].ValueType;
}
float IDataRecord.GetFloat(int i)
{
return (float)_Rows[_Ptr][i].Value;
}
Guid IDataRecord.GetGuid(int i)
{
return (Guid)_Rows[_Ptr][i].Value;
}
short IDataRecord.GetInt16(int i)
{
return (short)_Rows[_Ptr][i].Value;
}
int IDataRecord.GetInt32(int i)
{
return (int)_Rows[_Ptr][i].Value;
}
long IDataRecord.GetInt64(int i)
{
return (long)_Rows[_Ptr][i].Value;
}
string IDataRecord.GetName(int i)
{
return _Columns[i].ColumnName;
}
int IDataRecord.GetOrdinal(string name)
{
return _Columns.GetIndex(name);
}
string IDataRecord.GetString(int i)
{
return Convert.ToString(_Rows[_Ptr][i].Value);
}
object IDataRecord.GetValue(int i)
{
return _Rows[_Ptr][i].Value;
}
int IDataRecord.GetValues(object[] values)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = _Rows[_Ptr][i].Value;
}
return values.Length;
}
bool IDataRecord.IsDBNull(int i)
{
return _Rows[_Ptr][i].IsNull;
}
object IDataRecord.this[string name]
{
get
{
return _Rows[_Ptr][name];
}
}
object IDataRecord.this[int i]
{
get
{
return _Rows[i];
}
}
#endregion
#region IDataReader 成员
///
/// 清除所有行
///
void IDataReader.Close()
{
_Rows.Clear();
}
///
/// 获取数据行总数
///
int IDataReader.Depth
{
get
{
if (_Rows != null)
{
return _Rows.Count;
}
return 0;
}
}
DataTable IDataReader.GetSchemaTable()
{
return ToDataTable();
}
///
/// 是否已读取完所所有数据,并清空了记录。
///
bool IDataReader.IsClosed
{
get
{
return _Rows.Count == 0 && _Ptr >= _Rows.Count - 1;
}
}
///
/// 是否还有下一条数据
///
///
bool IDataReader.NextResult()
{
return _Ptr < _Rows.Count - 1;
}
///
/// 索引移到下一条,准备进行读取。
///
bool IDataReader.Read()
{
if (_Ptr < _Rows.Count - 1)
{
_Ptr++;
return true;
}
else
{
_Ptr = -1;
return false;
}
}
private int _RecordsAffected;
///
/// 返回(查询时)记录总数。
///
public int RecordsAffected
{
get
{
if (_RecordsAffected == 0)
{
return _Rows.Count;
}
return _RecordsAffected;
}
set
{
_RecordsAffected = value;
}
}
#endregion
#region IDisposable 成员
void IDisposable.Dispose()
{
_Rows.Clear();
_Rows = null;
}
#endregion
#region IEnumerable 成员
IEnumerator IEnumerable.GetEnumerator()
{
//for (int i = 0; i < Rows.Count; i++)
//{
// yield return Rows[i];
//}
return new System.Data.Common.DbEnumerator(this);
}
#endregion
}
public partial class MDataTable
{
#region 静态方法 CreateFrom
///
/// 不关闭Sdr(因为外部MProc.ExeMDataTableList还需要使用)
///
///
///
internal static MDataTable CreateFrom(DbDataReader sdr)
{
MDataTable mTable = new MDataTable("SysDefault");
if (sdr != null && sdr.FieldCount > 0)
{
DataTable dt = null;
bool noSchema = OracleDal.clientType == 0;
if (!noSchema)
{
try
{
dt = sdr.GetSchemaTable();
}
catch { noSchema = true; }
}
#region 读表结构
if (noSchema) //OracleClient 不支持子查询的GetSchemaTable,但ODP.NET是支持的。
{
//从DataReader读取表结构,不管有没有数据。
string hiddenFields = "," + AppConfig.DB.HiddenFields.ToLower() + ",";
MCellStruct mStruct;
for (int i = 0; i < sdr.FieldCount; i++)
{
string name = sdr.GetName(i);
if (string.IsNullOrEmpty(name))
{
name = "Empty_" + i;
}
bool isHiddenField = hiddenFields.IndexOf("," + name + ",", StringComparison.OrdinalIgnoreCase) > -1;
if (!isHiddenField)
{
mStruct = new MCellStruct(name, DataType.GetSqlType(sdr.GetFieldType(i)));
mStruct.ReaderIndex = i;
mTable.Columns.Add(mStruct);
}
}
}
else if (dt != null && dt.Rows.Count > 0)
{
TableSchema.FixTableSchemaType(sdr, dt);
mTable.Columns = TableSchema.GetColumns(dt);
mTable.Columns.dalType = DalCreate.GetDalTypeByReaderName(sdr.GetType().Name);
}
#endregion
if (sdr.HasRows)
{
MDataRow mRecord = null;
List errIndex = new List();//SQLite提供的dll不靠谱,sdr[x]类型转不过时,会直接抛异常
while (sdr.Read())
{
#region 读数据行
mRecord = mTable.NewRow(true);
for (int i = 0; i < mTable.Columns.Count; i++)
{
MCellStruct ms = mTable.Columns[i];
object value = null;
try
{
if (errIndex.Contains(i))
{
value = sdr.GetString(ms.ReaderIndex);
}
else
{
value = sdr[ms.ReaderIndex];
}
}
catch
{
if (!errIndex.Contains(i))
{
errIndex.Add(i);
}
value = sdr.GetString(ms.ReaderIndex);
}
if (value == null || value == DBNull.Value)
{
mRecord[i].Value = DBNull.Value;
mRecord[i].State = 0;
}
else if (Convert.ToString(value) == string.Empty)
{
mRecord[i].Value = string.Empty;
mRecord[i].State = 1;
}
else
{
mRecord[i].Value = value; //sdr.GetValue(i); 用此赋值,内部会进行类型转换。
mRecord[i].State = 1;//初始始状态为1
}
}
#endregion
}
}
}
return mTable;
}
///
/// 从List列表里加载成MDataTable
///
/// 实体列表对象
///
public static MDataTable CreateFrom(object entityList, BreakOp op)
{
MDataTable dt = new MDataTable("SysDefault");
if (entityList != null)
{
try
{
bool isObj = true;
Type t = entityList.GetType();
if (t.IsGenericType)
{
#region 处理列头
Type[] types;
int len = StaticTool.GetArgumentLength(ref t, out types);
if (len == 2)//字典
{
dt.Columns.Add("Key", DataType.GetSqlType(types[0]));
dt.Columns.Add("Value", DataType.GetSqlType(types[1]));
}
else
{
Type objType = types[0];
if ((objType.FullName.StartsWith("System.") && objType.FullName.Split('.').Length == 2) || objType.IsEnum)//系统类型。
{
isObj = false;
string name = objType.Name.Split('`')[0];
if (name.StartsWith("Nullable"))
{
name = Nullable.GetUnderlyingType(objType).Name;
}
dt.Columns.Add(name, DataType.GetSqlType(objType), false);
}
else
{
dt.TableName = objType.Name;
dt.Columns = TableSchema.GetColumns(objType);
}
}
#endregion
}
else if (entityList is Hashtable)
{
dt.Columns.Add("Key");
dt.Columns.Add("Value");
}
else
{
isObj = false;
dt.Columns.Add(t.Name.Replace("[]", ""), SqlDbType.Variant, false);
}
foreach (object o in entityList as IEnumerable)
{
MDataRow row = dt.NewRow();
if (isObj)
{
row.LoadFrom(o, op);//初始值状态为1
}
else
{
row.Set(0, o, 1);
}
dt.Rows.Add(row);
}
}
catch (Exception err)
{
Log.WriteLogToTxt(err);
}
}
return dt;
}
public static MDataTable CreateFrom(object entityList)
{
return CreateFrom(entityList, BreakOp.None);
}
public static MDataTable CreateFrom(NameObjectCollectionBase noc)
{
MDataTable dt = new MDataTable("SysDefault");
if (noc != null)
{
if (noc is NameValueCollection)
{
dt.Columns.Add("Key");
dt.Columns.Add("Value");
NameValueCollection nv = noc as NameValueCollection;
foreach (string key in nv)
{
dt.NewRow(true).Set(0, key, 1).Set(1, nv[key], 1);
}
}
else if (noc is HttpCookieCollection)
{
HttpCookieCollection nv = noc as HttpCookieCollection;
dt.Columns.Add("Name");
dt.Columns.Add("Value");
dt.Columns.Add("Expires");
dt.Columns.Add("Domain");
dt.Columns.Add("HttpOnly");
dt.Columns.Add("Path");
for (int i = 0; i < nv.Count; i++)
{
HttpCookie cookie = nv[i];
dt.NewRow(true).Set(0, cookie.Name).Set(1, cookie.Value)
.Set(2, cookie.Expires)
.Set(3, cookie.Domain)
.Set(4, cookie.HttpOnly)
.Set(5, cookie.Path);
}
}
else
{
dt = CreateFrom(noc as IEnumerable);
}
}
return dt;
}
///
/// 从Json或Xml字符串反加载成MDataTable
///
public static MDataTable CreateFrom(string jsonOrXml)
{
return CreateFrom(jsonOrXml, null);
}
public static MDataTable CreateFrom(string jsonOrXml, MDataColumn mdc)
{
return CreateFrom(jsonOrXml, mdc, JsonHelper.DefaultEscape);
}
///
/// 从Json或Xml字符串反加载成MDataTable
///
public static MDataTable CreateFrom(string jsonOrXml, MDataColumn mdc,EscapeOp op)
{
if (!string.IsNullOrEmpty(jsonOrXml))
{
if (jsonOrXml[0] == '<' || jsonOrXml.EndsWith(".xml"))
{
return CreateFromXml(jsonOrXml, mdc);
}
else
{
return JsonHelper.ToMDataTable(jsonOrXml, mdc,op);
}
}
return new MDataTable();
}
internal static MDataTable CreateFromXml(string xmlOrFileName, MDataColumn mdc)
{
MDataTable dt = new MDataTable();
if (mdc != null)
{
dt.Columns = mdc;
}
if (string.IsNullOrEmpty(xmlOrFileName))
{
return dt;
}
xmlOrFileName = xmlOrFileName.Trim();
XmlDocument doc = new XmlDocument();
bool loadOk = false;
if (!xmlOrFileName.StartsWith("<"))//可能是文件路径
{
dt.TableName = Path.GetFileNameWithoutExtension(xmlOrFileName);
dt.Columns = MDataColumn.CreateFrom(xmlOrFileName, false);
if (File.Exists(xmlOrFileName))
{
try
{
doc.Load(xmlOrFileName);
loadOk = true;
}
catch
{ }
}
}
else // xml 字符串
{
try
{
doc.LoadXml(xmlOrFileName);
loadOk = true;
}
catch
{
}
}
if (loadOk)
{
if (doc.DocumentElement.ChildNodes.Count > 0)
{
dt.TableName = doc.DocumentElement.Name;
if (dt.Columns.Count == 0)
{
//初如化表架构
bool useChildToGetSchema = doc.DocumentElement.ChildNodes[0].ChildNodes.Count > 0;
foreach (XmlNode item in doc.DocumentElement.ChildNodes)
{
if (useChildToGetSchema)
{
if (item.ChildNodes.Count > 0)//带子节点,用子节点的名称当字段
{
foreach (XmlNode child in item.ChildNodes)
{
if (!dt.Columns.Contains(child.Name))
{
dt.Columns.Add(child.Name);
}
}
}
}
else//不带子节点,用当前节点的属性当字段
{
if (item.Attributes != null && item.Attributes.Count > 0)//带子节点,用子节点的名称当字段
{
foreach (XmlAttribute attr in item.Attributes)
{
if (!dt.Columns.Contains(attr.Name))
{
dt.Columns.Add(attr.Name);
}
}
}
}
}
}
}
MDataRow dr = null;
foreach (XmlNode row in doc.DocumentElement.ChildNodes)
{
dr = dt.NewRow();
if (row.ChildNodes.Count > 0)//用子节点处理
{
foreach (XmlNode cell in row.ChildNodes)
{
if (!cell.InnerXml.StartsWith(" 0) //用属性处理
{
foreach (XmlAttribute cell in row.Attributes)
{
dr.Set(cell.Name, cell.Value.Trim(), 1);
}
dt.Rows.Add(dr);
}
}
}
return dt;
}
#endregion
#region 列的取值:Min、Max、Sum、Avg
private T GetMinMaxValue(int index, bool isMin)
{
if (Columns != null && index < Columns.Count && Rows != null && Rows.Count > 0)
{
List itemList = GetColumnItems(index, BreakOp.NullOrEmpty);
if (itemList.Count > 0)
{
itemList.Sort();
return isMin ? itemList[0] : itemList[itemList.Count - 1];
}
}
return default(T);
}
///
/// 获取列的最小值
///
/// 类型
/// 列名
///
public T Min(string columnName)
{
return GetMinMaxValue(Columns.GetIndex(columnName), true);
}
///
/// 获取列的最小值
///
/// 类型
/// 列索引
///
public T Min(int index)
{
return GetMinMaxValue(index, true);
}
///
/// 获取列的最大值
///
/// 类型
/// 列名
///
public T Max(string columnName)
{
return GetMinMaxValue(Columns.GetIndex(columnName), false);
}
///
/// 获取列的最大值
///
/// 类型
/// 列索引
///
public T Max(int index)
{
return GetMinMaxValue(index, false);
}
///
/// 汇总某列的值
///
/// 类型
/// 列名
///
public T Sum(string columnName)
{
return Sum(Columns.GetIndex(columnName));
}
///
/// 汇总某列的值
///
/// 类型
/// 列索引
///
public T Sum(int index)
{
if (Columns != null && index < Columns.Count && Rows != null && Rows.Count > 0)
{
List itemList = GetColumnItems(index, BreakOp.NullOrEmpty);
if (itemList.Count > 0)
{
Decimal sum = 0;
for (int i = 0; i < itemList.Count; i++)
{
sum += itemList[i];
}
return (T)StaticTool.ChangeType(sum, typeof(T));
}
}
return default(T);
}
///
/// 记算某列的平均值
///
/// 类型
/// 列名
///
public T Avg(string columnName)
{
return Avg(Columns.GetIndex(columnName));
}
///
///记算某列的平均值
///
/// 类型
/// 列索引
///
public T Avg(int index)
{
Decimal sum = Sum(index);
if (sum > 0)
{
return (T)StaticTool.ChangeType(sum / Rows.Count, typeof(T));
}
return default(T);
}
///
/// 行转换列(不指定时,默认取最后三列处理)
///
public MDataTable Pivot()
{
if (Columns.Count < 3)
{
Error.Throw("At least three columns when call Pivot()");
}
int count = Columns.Count;
return Pivot(Columns[count - 3].ColumnName, Columns[count - 2].ColumnName, Columns[count - 1].ColumnName);
}
///
/// 行转换列
///
/// 用于指定行的列名
/// 用于分拆成列的列名
/// 用于显示值的列名
///
public MDataTable Pivot(string rowName, string colName, string valueName)
{
MDataTable dt = new MDataTable(TableName);
#region 处理列头
List colNameItems = GetColumnItems(colName, BreakOp.NullOrEmpty, true);
if (colNameItems == null || colNameItems.Count == 0 || colNameItems.Count > 255)
{
return dt;
}
dt.Columns.Add(rowName);
for (int i = 0; i < colNameItems.Count; i++)
{
dt.Columns.Add(colNameItems[i]);
}
#endregion
#region 处理数据
List rowNameItems = GetColumnItems(rowName, BreakOp.None, true);
MDataTable splitTable = this;
for (int i = 0; i < rowNameItems.Count; i++)
{
MDataRow nameRow = dt.NewRow(true).Set(0, rowNameItems[i]);//新表的一行
MDataTable[] dt2 = splitTable.Split(rowName + "='" + rowNameItems[i] + "'");//筛选分隔
splitTable = dt2[1];//剩下的作为下次分隔
foreach (MDataRow row in dt2[0].Rows)//填写数据
{
if (!row[colName].IsNullOrEmpty)//列名不能为空或Null
{
nameRow.Set(row[colName].Value, row[valueName].Value);
}
}
}
#endregion
return dt;
}
#endregion
//给MDataTableBatchAction的批量更新使用。
internal void Load(MDataTable dt, MCellStruct primary)
{
if (dt == null || dt.Rows.Count == 0)
{
return;
}
string pkName = primary != null ? primary.ColumnName : Columns.FirstPrimary.ColumnName;
int i1 = Columns.GetIndex(pkName);
MDataRow rowA, rowB;
for (int i = 0; i < Rows.Count; i++)
{
rowA = Rows[i];
rowB = dt.FindRow(pkName + "='" + rowA[i1].StringValue + "'");
if (rowB != null)
{
rowA.LoadFrom(rowB, RowOp.IgnoreNull, false);
}
}
}
#region 注释掉代码
/*
*
///
/// 从List列表里加载成MDataTable
///
/// 实体列表
///
public static MDataTable LoadFromList(List entityList) where T : class
{
MDataTable dt = new MDataTable("Default");
if (entityList != null && entityList.Count > 0)
{
dt.Columns = SchemaCreate.GetColumns(entityList[0].GetType());
//生成表结构。
foreach (T entity in entityList)
{
MDataRow row = dt.NewRow();
row.LoadFrom(entity);
dt.Rows.Add(row);
}
}
return dt;
}
///
/// 快速创建表架构(无ID列名时,系统自动创建自增型的ID列到首列。)
///
/// 文件名
/// 指定的文件存在时,是否允许复盖
/// 创建的列名
/// 列名对应的数据类型(不指定则默认为nvarchar)
public static void CreateSchema(string fileName, bool overwrite, string[] columnNames, params SqlDbType[] sqlDbTypes)
{
if (columnNames.Length >= 0)
{
if (fileName[1] != ':')
{
fileName = AppConfig.WebRootPath + fileName;
}
fileName = fileName.Replace(Path.GetExtension(fileName), string.Empty) + ".ts";
if (!File.Exists(fileName) || overwrite)
{
MDataColumn mdc = new MDataColumn();
string columnName = string.Empty;
for (int i = 0; i < columnNames.Length; i++)
{
columnName = columnNames[i];
if (sqlDbTypes != null && sqlDbTypes.Length > i)
{
mdc.Add(columnName, sqlDbTypes[i]);
}
else
{
mdc.Add(columnName);
}
}
if (mdc[0].ColumnName.ToLower() != "id")
{
MCellStruct cellStruct = new MCellStruct("ID", SqlDbType.Int, true, false, -1);
cellStruct.IsPrimaryKey = true;
mdc.Insert(0, cellStruct);
}
else if (mdc[0].SqlType == SqlDbType.Int)
{
mdc[0].IsAutoIncrement = true;
mdc[0].IsPrimaryKey = true;
}
mdc.WriteSchema(fileName);
}
}
}
* */
#endregion
}
}