using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Collections; using System.ComponentModel; using CYQ.Data.SQL; using CYQ.Data.Tool; using System.Reflection; using System.Collections.Specialized; using CYQ.Data.UI; using CYQ.Data.Json; namespace CYQ.Data.Table { /// /// 一行记录 /// public partial class MDataRow : IDataRecord { List _CellList; List CellList { get { if (_CellList.Count == 0 && _Table != null && _Table.Columns.Count > 0) { MCellStruct cellStruct; foreach (MCellStruct item in _Table.Columns) { cellStruct = item; MDataCell cell = new MDataCell(ref cellStruct, null); _CellList.Add(cell); } } return _CellList; } set { _CellList = value; } } public MDataRow() { CellList = new List(); } public MDataRow(MDataTable dt) { if (dt != null) { _Table = dt; CellList = new List(dt.Columns.Count); } } public MDataRow(MDataColumn mdc) { CellList = new List(mdc.Count); Table.Columns = mdc; //Table.Columns.AddRange(mdc); } /// /// 获取列头 /// public MDataColumn Columns { get { return Table.Columns; } } public static implicit operator MDataRow(DataRow row) { if (row == null) { return null; } MDataRow mdr = new MDataRow(); mdr.TableName = row.Table.TableName; DataColumnCollection columns = row.Table.Columns; if (columns != null && columns.Count > 0) { for (int i = 0; i < columns.Count; i++) { MCellStruct cellStruct = new MCellStruct(columns[i].ColumnName, DataType.GetSqlType(columns[i].DataType), columns[i].ReadOnly, columns[i].AllowDBNull, columns[i].MaxLength); cellStruct.DefaultValue = columns[i].DefaultValue; mdr.Add(new MDataCell(ref cellStruct, row[i])); } } return mdr; } private string _Conn = string.Empty; /// /// 所依属的数据库配置项名称[当MAction从带有架构的行加载时,此链接若存在,优先成为默认的数据库链接] /// public string Conn { get { if (_Table != null) { return _Table.Conn; } else if (string.IsNullOrEmpty(_Conn)) { return AppConfig.DB.DefaultConn; } return _Conn; } set { if (_Table != null) { _Table.Conn = value; } else { _Conn = value; } } } private string _TableName; /// /// 原始表名[未经过多数据库兼容处理] /// public string TableName { get { if (_Table != null) { return _Table.TableName; } return _TableName; } set { if (_Table != null) { _Table.TableName = value; } else { _TableName = value; } } } [NonSerialized] private object _DynamicData; /// /// 动态存储数据 /// public object DynamicData { get { return _DynamicData; } set { _DynamicData = value; } } /// /// 输入枚举型数据 /// public MDataCell this[object field] { get { if (field == null) { return null; } if (field is int || (field is Enum && AppConfig.DB.IsEnumToInt)) { int index = (int)field; if (Count > index) { return this[index]; } } else if (field is string) { return this[field as string]; } //else if (field is IField) //{ // IField iFiled = field as IField; // if (iFiled.ColID > -1) // { // return this[iFiled.ColID]; // } // return this[iFiled.Name]; //} return this[field.ToString()]; } } public MDataCell this[string key] { get { int index = Columns.GetIndex(key);//重新检测列是否一致。; if (index == -1) { if (key.Length < 3) //2<=20 { //判断是否为数字。 if (!int.TryParse(key, out index)) { index = -1; } } } if (index > -1) { return this[index]; } return null; } } public MDataCell this[int index] { get { if (index > -1 && index < Count) { return CellList[index]; } return null; } set { Error.Throw(AppConst.Global_NotImplemented); } } private MDataTable _Table; /// /// 获取该行拥有其架构的 MDataTable。 /// [JsonIgnore] public MDataTable Table { get { if (_Table == null) { _Table = new MDataTable(_TableName); if (this.Count > 0) { foreach (MDataCell cell in this) { _Table.Columns.Add(cell.Struct); } } _Table.Rows.Add(this); } return _Table; } internal set { _Table = value; } } /// /// 通过一个数组来获取或设置此行的所有值。 /// [JsonIgnore] public object[] ItemArray { get { object[] values = new object[Count]; for (int i = 0; i < values.Length; i++) { values[i] = this[i].Value; } return values; } } private string _RowError; /// /// 获取或设置行的自定义错误说明。 /// public string RowError { get { return _RowError; } set { _RowError = value; } } /// /// 获取第一个关键主键列 /// public MDataCell PrimaryCell { get { return JointPrimaryCell[0]; } } private List _JointPrimaryCell; /// /// 获取联合主键列表(若有多个主键) /// public List JointPrimaryCell { get { if (_JointPrimaryCell == null && Columns.Count > 0) { _JointPrimaryCell = new List(Columns.JointPrimary.Count); foreach (MCellStruct st in Columns.JointPrimary) { _JointPrimaryCell.Add(this[st.ColumnName]); } } return _JointPrimaryCell; } } /// /// 此方法被Emit所调用 /// public object GetItemValue(string index)//必须Public { MDataCell cell = this[index]; if (cell == null || cell.Value == null || cell.Value == DBNull.Value) { return null; } return cell.Value; } /// /// 此方法被Emit所调用 /// public object GetItemValue(int index)//必须Public { MDataCell cell = this[index]; if (cell == null || cell.Value == null || cell.Value == DBNull.Value) { return null; } return cell.Value; } /// /// 返回数组值 /// /// public object[] GetItemValues() { object[] values = new object[Columns.Count]; for (int i = 0; i < this.Count; i++) { values[i] = this[i].Value; } return values; } /// /// 取值 /// public T Get(object key) { return Get(key, default(T)); } public T Get(object key, T defaultValue) { MDataCell cell = this[key]; if (cell == null || cell.IsNull) { return defaultValue; } return cell.Get(); } /// /// 将行的数据转成两列(ColumnName、Value)的表 /// public MDataTable ToTable() { MDataTable dt = this.Columns.ToTable(); MCellStruct msValue = new MCellStruct("Value", SqlDbType.Variant); MCellStruct msState = new MCellStruct("State", SqlDbType.Int); dt.Columns.Insert(1, msValue); dt.Columns.Insert(2, msState); for (int i = 0; i < Count; i++) { dt.Rows[i][1].Value = this[i].Value; dt.Rows[i][2].Value = this[i].State; } return dt; } /// /// 将行的数据转成两列(ColumnName、Value、State)的表 /// /// 仅数据(不含列头结构) /// public MDataTable ToTable(bool onlyData) { if (onlyData) { MDataTable dt = new MDataTable(this.TableName); dt.Columns.Add("ColumnName", SqlDbType.NVarChar); dt.Columns.Add("Value", SqlDbType.Variant); dt.Columns.Add("State", SqlDbType.Int); for (int i = 0; i < Count; i++) { MDataCell cell = this[i]; dt.NewRow(true) .Set(0, cell.ColumnName) .Set(1, cell.Value) .Set(2, cell.State); } return dt; } return ToTable(); } /// /// 将行的数据行的值全重置为Null /// public void Clear() { for (int i = 0; i < this.Count; i++) { this[i].Clear(); } } /// /// 获取行的当前状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]] /// /// public int GetState() { return GetState(false); } /// /// 获取行的当前状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]] /// public int GetState(bool ignorePrimaryKey) { int state = 0; for (int i = 0; i < this.Count; i++) { MDataCell cell = this[i]; if (ignorePrimaryKey && cell.Struct.IsPrimaryKey) { continue; } state = cell.State > state ? cell.State : state; } return state; } /// /// 为行连续设置值多个值 /// /// 起始行索引||起始列名 /// 多个值 /// public MDataRow Sets(object startKey, params object[] values) { MDataCell cell = this[startKey]; if (cell != null) { int startIndex = cell.Struct.ReaderIndex; for (int i = 0; i < values.Length; i++) { Set(startIndex + i, values[i]); } } return this; } /// /// 为行设置值 /// public MDataRow Set(object key, object value) { return Set(key, value, -1); } /// /// 为行设置值 /// /// 字段名 /// 值 /// 手工设置状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]] public MDataRow Set(object key, object value, int state) { MDataCell cell = this[key]; if (cell != null) { cell.Value = value; if (state > -1 && state < 3) { cell.State = state; } } return this; } /// /// 将行的数据行的状态全部重置 /// /// 状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]] public MDataRow SetState(int state) { return SetState(state, BreakOp.None); } /// /// 将行的数据行的状态全部重置 /// /// 状态[0:未更改;1:已赋值,值相同[可插入];2:已赋值,值不同[可更新]] /// 状态设置选项 public MDataRow SetState(int state, BreakOp op) { return SetState(state, op, string.Empty); } /// 批量指定某些列 /// public MDataRow SetState(int state, BreakOp op, string columns) { if (!string.IsNullOrEmpty(columns)) { string[] items = columns.Trim(',', ' ').Split(','); for (int i = 0; i < items.Length; i++) { MDataCell cell = this[items[i]]; if (cell != null) { SetState(state, op, cell); } } } else { for (int i = 0; i < this.Count; i++) { SetState(state, op, this[i]); } } return this; } private void SetState(int state, BreakOp op, MDataCell cell) { switch (op) { case BreakOp.Null: if (cell.IsNull) { cell.State = 0; return; } break; case BreakOp.Empty: if (cell.StringValue == "") { cell.State = 0; return; } break; case BreakOp.NullOrEmpty: if (cell.IsNullOrEmpty) { cell.State = 0; return; } break; } cell.State = state; } /// /// 无参时默认自-1 /// internal void SetState() { for (int i = 0; i < this.Count; i++) { if (this[i].State == 2) { this[i].State = 1; } } } #region ICloneable 成员 /// /// 复制一行 /// /// public MDataRow Clone() { MDataRow row = new MDataRow(); for (int i = 0; i < Count; i++) { MCellStruct mcb = this[i].Struct; MDataCell mdc = new MDataCell(ref mcb); mdc.LoadValue(this[i], true); row.Add(mdc); } //row._Table = _Table;//不能带,会造成单行移除列时,移除的是原引用的行,而不是自身 row.RowError = RowError; row.TableName = TableName; row.Conn = Conn; return row; } #endregion #region IDataRecord 成员 int IDataRecord.FieldCount { get { return Count; } } bool IDataRecord.GetBoolean(int i) { return (bool)this[i].Value; } byte IDataRecord.GetByte(int i) { return (byte)this[i].Value; } long IDataRecord.GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) { return (byte)this[i].Value; } char IDataRecord.GetChar(int i) { return (char)this[i].Value; } long IDataRecord.GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) { return (long)this[i].Value; } IDataReader IDataRecord.GetData(int i) { return null; } string IDataRecord.GetDataTypeName(int i) { //return ""; return this[i].Struct.SqlTypeName; } DateTime IDataRecord.GetDateTime(int i) { return (DateTime)this[i].Value; } decimal IDataRecord.GetDecimal(int i) { return (decimal)this[i].Value; } double IDataRecord.GetDouble(int i) { return (double)this[i].Value; } Type IDataRecord.GetFieldType(int i) { return this[i].Struct.ValueType; } float IDataRecord.GetFloat(int i) { return (float)this[i].Value; } Guid IDataRecord.GetGuid(int i) { return (Guid)this[i].Value; } short IDataRecord.GetInt16(int i) { return (short)this[i].Value; } int IDataRecord.GetInt32(int i) { return (int)this[i].Value; } long IDataRecord.GetInt64(int i) { return (long)this[i].Value; } string IDataRecord.GetName(int i) { return this[i].ColumnName; } int IDataRecord.GetOrdinal(string name) { return this.Columns.GetIndex(name); } string IDataRecord.GetString(int i) { return (string)this[i].Value; } object IDataRecord.GetValue(int i) { return this[i].Value; } int IDataRecord.GetValues(object[] values) { if (values != null && this.Count == values.Length) { for (int i = 0; i < this.Count; i++) { values[i] = this[i].Value; } } return this.Count; } bool IDataRecord.IsDBNull(int i) { return this[i].IsNull; } object IDataRecord.this[string name] { get { return this[name]; } } object IDataRecord.this[int i] { get { return this[i]; } } #endregion } public partial class MDataRow : IList { public int Count { get { return CellList.Count; } } public void Add(string columnName, object value) { Add(columnName, SqlDbType.NVarChar, value); } public void Add(string columnName, SqlDbType sqlType, object value) { MCellStruct cs = new MCellStruct(columnName, sqlType, false, true, -1); Add(new MDataCell(ref cs, value)); } public void Add(MDataCell cell) { CellList.Add(cell); Columns.Add(cell.Struct); } public void Insert(int index, MDataCell cell) { CellList.Insert(index, cell); Columns.Insert(index, cell.Struct); } public void Remove(string columnName) { int index = Columns.GetIndex(columnName); if (index > -1) { RemoveAt(index); } } public bool Remove(MDataCell item) { if (Columns.Count == Count) { Columns.Remove(item.Struct); } else { CellList.Remove(item); } return true; } public void RemoveAt(int index) { if (Columns.Count == Count) { Columns.RemoveAt(index); } else { CellList.RemoveAt(index); } } #region IList 成员 int IList.IndexOf(MDataCell item) { return CellList.IndexOf(item); } #endregion #region ICollection 成员 public bool Contains(MDataCell item) { return CellList.Contains(item); } void ICollection.CopyTo(MDataCell[] array, int arrayIndex) { CellList.CopyTo(array, arrayIndex); } bool ICollection.IsReadOnly { get { return false; } } #endregion #region IEnumerable 成员 IEnumerator IEnumerable.GetEnumerator() { return CellList.GetEnumerator(); } #endregion #region IEnumerable 成员 IEnumerator IEnumerable.GetEnumerator() { return CellList.GetEnumerator(); } #endregion } //扩展交互部分 public partial class MDataRow { /// /// 从实体、Json、Xml、IEnumerable接口实现的类、MDataRow /// /// public static MDataRow CreateFrom(object anyObj) { return CreateFrom(anyObj, null, BreakOp.None, JsonHelper.DefaultEscape); } public static MDataRow CreateFrom(object anyObj, Type valueType) { return CreateFrom(anyObj, valueType, BreakOp.None, JsonHelper.DefaultEscape); } public static MDataRow CreateFrom(object anyObj, Type valueType, BreakOp op) { return CreateFrom(anyObj, valueType, op, JsonHelper.DefaultEscape); } /// /// 从实体、Json、Xml、IEnumerable接口实现的类、MDataRow /// public static MDataRow CreateFrom(object anyObj, Type valueType, BreakOp breakOp, EscapeOp escapeOp) { MDataRow row = new MDataRow(); if (anyObj is MDataRow) { row.LoadFrom(anyObj as MDataRow, (breakOp == BreakOp.Null ? RowOp.IgnoreNull : RowOp.None), true); } else if (anyObj is string) { row.LoadFrom(anyObj as string, escapeOp, breakOp); } else if (anyObj is IEnumerable) { row.LoadFrom(anyObj as IEnumerable, valueType, escapeOp, breakOp); } else { row.LoadFrom(anyObj, breakOp); } row.SetState(1);//外部创建的状态默认置为1. return row; } /// /// 输出行的数据Json /// public string ToJson() { return ToJson(RowOp.IgnoreNull, false, EscapeOp.Default); } public string ToJson(bool isConvertNameToLower) { return ToJson(RowOp.IgnoreNull, isConvertNameToLower); } /// /// 输出行的数据Json /// public string ToJson(RowOp op) { return ToJson(op, false, EscapeOp.Default); } public string ToJson(RowOp op, bool isConvertNameToLower) { return ToJson(op, isConvertNameToLower, EscapeOp.Default); } /// /// 输出Json /// /// 过滤条件 /// 转义选项 /// public string ToJson(RowOp op, bool isConvertNameToLower, EscapeOp escapeOp) { return JsonHelper.ToJson(this, isConvertNameToLower, op, escapeOp); //JsonHelper helper = new JsonHelper(); //if (DynamicData != null && DynamicData is MDictionary) //{ // helper.LoopCheckList = DynamicData as MDictionary;//继承父的数据,避免循环引用父 // helper.Level = helper.LoopCheckList[helper.LoopCheckList.Count - 1] + 1; //} //helper.IsConvertNameToLower = isConvertNameToLower; //helper.Escape = escapeOp; //helper.RowOp = op; //helper.Fill(this); //return helper.ToString(); } internal string ToXml(bool isConvertNameToLower) { string xml = string.Empty; foreach (MDataCell cell in this) { xml += cell.ToXml(isConvertNameToLower); } return xml; } /* //public bool WriteJson(string fileName) //{ // return WriteJson(fileName, RowOp.IgnoreNull); //} /// /// 将json保存到指定文件中 /// public bool WriteJson(string fileName, RowOp op) { return IOHelper.Write(fileName, ToJson(op)); } */ /// /// 转实体类 /// /// 类型 /// public T ToEntity() { Type t = typeof(T); return (T)ToEntity(t); } internal object ToEntity(Type t) { if (t.Name == "MDataRow") { return this; } #if NETSTANDARD1_0_OR_GREATER return GetObj(t, this);//标准库无法用Emit #else bool isOrmBaseOrNotCustom = t.BaseType.Name == "OrmBase" || (t.BaseType.BaseType != null && t.BaseType.BaseType.Name == "OrmBase"); if (!isOrmBaseOrNotCustom) { isOrmBaseOrNotCustom = ReflectTool.GetSystemType(ref t) != SysType.Custom; } if (isOrmBaseOrNotCustom) { return GetObj(t, this);//远程代理实体的属性会变,无法用Emit,如果不是实体类,也无法用Emit } else { return FastToT.Create(t, this.Columns)(this); } #endif } private object GetValue(MDataRow row, Type type) { switch (ReflectTool.GetSystemType(ref type)) { case SysType.Base: return ConvertTool.ChangeType(row[0].Value, type); case SysType.Enum: return Enum.Parse(type, row[0].ToString()); default: object o = Activator.CreateInstance(type); SetToEntity(ref o, row); return o; } } /// /// 将值批量赋给UI /// public void SetToAll(params object[] parentControls) { SetToAll(null, parentControls); } /// /// 将值批量赋给UI /// /// 自动前缀,多个可用逗号分隔 /// 页面控件 public void SetToAll(string autoPrefix, params object[] parentControls) { if (Count > 0) { MDataRow row = this; using (MActionUI mui = new MActionUI(ref row, null, null)) { if (!string.IsNullOrEmpty(autoPrefix)) { string[] pres = autoPrefix.Split(','); mui.SetAutoPrefix(pres[0], pres); } mui.SetAll(parentControls); } } } /// /// 从Web Post表单里取值。 /// public void LoadFrom() { LoadFrom(true); } /// /// 从Web Post表单里取值 或 从Winform、WPF的表单控件里取值。 /// True为Web应用,反之为Win应用 /// Web时设置前缀,Win时设置父容器控件 /// public void LoadFrom(bool isWeb, params object[] prefixOrParentControl) { if (Count > 0) { MDataRow row = this; using (MActionUI mui = new MActionUI(ref row, null, null)) { if (prefixOrParentControl.Length > 0) { if (isWeb) { string[] items = prefixOrParentControl as string[]; mui.SetAutoPrefix(items[0], items); } else { mui.SetAutoParentControl(prefixOrParentControl[0], prefixOrParentControl); } } mui.GetAll(false); } } } /// /// 从别的行加载值 /// public void LoadFrom(MDataRow row) { LoadFrom(row, RowOp.None, Count == 0); } /// /// 从别的行加载值 /// public void LoadFrom(MDataRow row, RowOp rowOp, bool isAllowAppendColumn) { LoadFrom(row, rowOp, isAllowAppendColumn, true); } /// /// 从别的行加载值 /// /// 要加载数据的行 /// 行选项[从其它行加载的条件] /// 如果row带有新列,是否加列 /// 是否同时加载值的状态[默认值为:true] public void LoadFrom(MDataRow row, RowOp rowOp, bool isAllowAppendColumn, bool isWithValueState) { if (row != null) { if (isAllowAppendColumn) { for (int i = 0; i < row.Count; i++) { //if (rowOp == RowOp.IgnoreNull && row[i].IsNull) //{ // continue; //} if (!Columns.Contains(row[i].ColumnName)) { Columns.Add(row[i].Struct); } } } MDataCell rowCell; foreach (MDataCell cell in this) { rowCell = row[cell.ColumnName]; if (rowCell == null || (rowOp == RowOp.IgnoreNull && rowCell.IsNull)) { continue; } if (rowOp == RowOp.None || rowCell.State >= (int)rowOp) { cell.LoadValue(rowCell, isWithValueState); //if (cell.Struct.SqlType == rowCell.Struct.SqlType) //{ // cell.CellValue.StringValue = rowCell.StringValue; // cell.CellValue.Value = rowCell.CellValue.Value; // cell.CellValue.IsNull = rowCell.CellValue.IsNull; //} //else //{ //cell.Value = rowCell.Value;//用属于赋值,因为不同的架构,类型若有区别如 int[access] int64[sqlite],在转换时会出错 //cell._CellValue.IsNull = rowCell._CellValue.IsNull;// //} //if (isWithValueState) //{ // cell.State = rowCell.State; //} } } } } /// /// 从数组里加载值 /// /// public void LoadFrom(object[] values) { if (values != null && values.Length <= Count) { for (int i = 0; i < values.Length; i++) { this[i].Value = values[i]; } } } public void LoadFrom(string json) { LoadFrom(json, JsonHelper.DefaultEscape); } /// /// 从json里加载值 /// public void LoadFrom(string json, EscapeOp op) { LoadFrom(json, op, BreakOp.None); } /// /// 从json里加载值 /// public void LoadFrom(string json, EscapeOp op, BreakOp breakOp) { if (!string.IsNullOrEmpty(json)) { Dictionary dic = JsonHelper.Split(json); if (dic != null && dic.Count > 0) { LoadFrom(dic, null, op, breakOp); } } else { LoadFrom(true); } } /// /// 从泛型字典集合里加载 /// public void LoadFrom(IEnumerable dic) { LoadFrom(dic, null, JsonHelper.DefaultEscape, BreakOp.None); } internal void LoadFrom(IEnumerable dic, Type valueType, EscapeOp op, BreakOp breakOp) { if (dic != null) { if (dic is MDataRow) { LoadFrom(dic as MDataRow, RowOp.None, true); return; } bool isNameValue = dic is NameValueCollection; bool isAddColumn = Columns.Count == 0; SqlDbType sdt = SqlDbType.NVarChar; if (isAddColumn) { if (valueType != null) { sdt = DataType.GetSqlType(valueType); } else if (!isNameValue) { Type type = dic.GetType(); if (type.IsGenericType) { sdt = DataType.GetSqlType(type.GetGenericArguments()[1]); } else { sdt = SqlDbType.Variant; } } } string key = null; object value = null; Type t = null; PropertyInfo keyPro = null; PropertyInfo valuePro = null; int i = -1; foreach (object o in dic) { i++; if (isNameValue) { if (o == null) { key = "null"; value = ((NameValueCollection)dic)[i]; } else { key = Convert.ToString(o); value = ((NameValueCollection)dic)[key]; } } else { if (t == null) { t = o.GetType(); keyPro = t.GetProperty("Key"); valuePro = t.GetProperty("Value"); } value = valuePro.GetValue(o, null); bool isContinue = false; switch (breakOp) { case BreakOp.Null: if (value == null) { isContinue = true; } break; case BreakOp.Empty: if (value != null && Convert.ToString(value) == "") { isContinue = true; } break; case BreakOp.NullOrEmpty: if (Convert.ToString(value) == "") { isContinue = true; } break; } if (isContinue) { continue; } key = Convert.ToString(keyPro.GetValue(o, null)); //if (value != null) //{ //} } //if (value != null) //{ if (isAddColumn) { SqlDbType sdType = sdt; if (sdt == SqlDbType.Variant) { if (value == null) { sdType = SqlDbType.NVarChar; } else { sdType = DataType.GetSqlType(value.GetType()); } } Add(key, sdType, value); } else { if (value != null && value is string) { value = JsonHelper.UnEscape(value.ToString(), op); } Set(key, value); } // } } } } internal void LoadFrom2(IEnumerable dic, Type valueType, EscapeOp op, BreakOp breakOp) { if (dic != null) { if (dic is MDataRow) { LoadFrom(dic as MDataRow, RowOp.None, true); return; } bool isNameValue = dic is NameValueCollection; bool isAddColumn = Columns.Count == 0; SqlDbType sdt = SqlDbType.NVarChar; if (isAddColumn) { if (valueType != null) { sdt = DataType.GetSqlType(valueType); } else if (!isNameValue) { Type type = dic.GetType(); if (type.IsGenericType) { sdt = DataType.GetSqlType(type.GetGenericArguments()[1]); } else { sdt = SqlDbType.Variant; } } } string key = null; object value = null; Type t = null; PropertyInfo keyPro = null; PropertyInfo valuePro = null; int i = -1; foreach (object o in dic) { i++; if (isNameValue) { if (o == null) { key = "null"; value = ((NameValueCollection)dic)[i]; } else { key = Convert.ToString(o); value = ((NameValueCollection)dic)[key]; } } else { if (t == null) { t = o.GetType(); keyPro = t.GetProperty("Key"); valuePro = t.GetProperty("Value"); } value = valuePro.GetValue(o, null); bool isContinue = false; switch (breakOp) { case BreakOp.Null: if (value == null) { isContinue = true; } break; case BreakOp.Empty: if (value != null && Convert.ToString(value) == "") { isContinue = true; } break; case BreakOp.NullOrEmpty: if (Convert.ToString(value) == "") { isContinue = true; } break; } if (isContinue) { continue; } key = Convert.ToString(keyPro.GetValue(o, null)); //if (value != null) //{ //} } //if (value != null) //{ if (isAddColumn) { SqlDbType sdType = sdt; if (sdt == SqlDbType.Variant) { if (value == null) { sdType = SqlDbType.NVarChar; } else { sdType = DataType.GetSqlType(value.GetType()); } } Add(key, sdType, value); } else { if (value != null && value is string) { value = JsonHelper.UnEscape(value.ToString(), op); } Set(key, value); } // } } } } /// /// 将实体转成数据行。 /// /// 实体对象 public void LoadFrom(object entity) { if (entity == null || entity is Boolean) { LoadFrom(true); } else if (entity is String) { LoadFrom(entity as String); } else if (entity is MDataRow) { LoadFrom(entity as MDataRow); } else if (entity is IEnumerable) { LoadFrom(entity as IEnumerable); } else { LoadFrom(entity, BreakOp.None); } } /// /// 将实体转成数据行。 /// /// 实体对象 public void LoadFrom(object entity, BreakOp op) { LoadFrom(entity, op, 2); } /// /// 将实体转成数据行。 /// /// 实体对象 /// 跳过设置的选项 /// 初始值:0无法插入和更新;1可插入;2可插入可更新(默认值) public void LoadFrom(object entity, BreakOp op, int initState) { if (entity == null) { return; } try { Type t = entity.GetType(); if (Columns.Count == 0) { MDataColumn mcs = TableSchema.GetColumnByType(t); MCellStruct ms = null; for (int i = 0; i < mcs.Count; i++) { ms = mcs[i]; MDataCell cell = new MDataCell(ref ms); Add(cell); } } if (string.IsNullOrEmpty(TableName)) { TableName = t.Name; } List pis = ReflectTool.GetPropertyList(t); if (pis.Count > 0) { foreach (PropertyInfo p in pis) { SetValueToCell(entity, op, p, null, initState); } } List fis = ReflectTool.GetFieldList(t); if (fis.Count > 0) { foreach (FieldInfo f in fis) { SetValueToCell(entity, op, null, f, initState); } } } catch (Exception err) { Log.Write(err, LogType.Error); } } private void SetValueToCell(object entity, BreakOp op, PropertyInfo p, FieldInfo f, int initState) { string name = p != null ? p.Name : f.Name; int index = Columns.GetIndex(name); if (index > -1) { object objValue = p != null ? p.GetValue(entity, null) : f.GetValue(entity); Type type = p != null ? p.PropertyType : f.FieldType; if (type.IsEnum) { if (ReflectTool.GetAttr(p, f) != null) { objValue = objValue.ToString(); } else if (ReflectTool.GetAttr(p, f) != null) { FieldInfo field = type.GetField(objValue.ToString()); if (field != null) { DescriptionAttribute da = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute; if (da != null) { objValue = da.Description; } } } } switch (op) { case BreakOp.Null: if (objValue == null) { return; } break; case BreakOp.Empty: if (Convert.ToString(objValue) == "") { return; } break; case BreakOp.NullOrEmpty: if (objValue == null || Convert.ToString(objValue) == "") { return; } break; } Set(index, objValue, initState);//外部状态1,内部默认是2。 } } /// /// 将行中的数据值赋给实体对象 /// /// 实体对象 public void SetToEntity(object obj) { SetToEntity(obj, RowOp.IgnoreNull); } public void SetToEntity(object obj, RowOp op) { SetToEntity(ref obj, this, op); } /// /// 将指定行的数据赋给实体对象。 /// /// /// internal void SetToEntity(ref object obj, MDataRow row) { SetToEntity(ref obj, row, RowOp.IgnoreNull); } internal void SetToEntity(ref object obj, MDataRow row, RowOp op) { if (obj == null || row == null || row.Count == 0) { return; } Type objType = obj.GetType(); string objName = objType.FullName, cellName = ""; try { #region 处理核心 List pis = ReflectTool.GetPropertyList(objType); if (pis.Count > 0) { foreach (PropertyInfo p in pis)//遍历实体 { if (p.CanWrite) { SetValueToPropertyOrField(ref obj, row, p, null, op, out cellName); } } } else { List fis = ReflectTool.GetFieldList(objType); if (fis.Count > 0) { foreach (FieldInfo f in fis)//遍历实体 { SetValueToPropertyOrField(ref obj, row, null, f, op, out cellName); } } } #endregion } catch (Exception err) { string msg = "[AttachInfo]:" + string.Format("ObjName:{0} PropertyName:{1}", objName, cellName) + "\r\n"; msg += Log.GetExceptionMessage(err); Log.WriteLogToTxt(msg, LogType.Error); } } private void SetValueToPropertyOrField(ref object obj, MDataRow row, PropertyInfo p, FieldInfo f, RowOp op, out string cellName) { cellName = p != null ? p.Name : f.Name; MDataCell cell = row[cellName]; if (cell == null) { return; } if (op == RowOp.IgnoreNull && cell.IsNull) { return; } else if (op == RowOp.Insert && cell.State == 0) { return; } else if (op == RowOp.Update && cell.State != 2) { return; } Type propType = p != null ? p.PropertyType : f.FieldType; object objValue = GetObj(propType, cell.Value); if (p != null) { p.SetValue(obj, objValue, null); } else { f.SetValue(obj, objValue); } } internal object GetObj(Type toType, object objValue) { if (objValue == null) { return null; } Type propType = toType; string value = Convert.ToString(objValue); object returnObj = null; SysType sysType = ReflectTool.GetSystemType(ref propType); switch (sysType) { case SysType.Enum: returnObj = ConvertTool.ChangeType(objValue, toType);// Enum.Parse(propType, value); break; case SysType.Base: #region 基础类型处理 if (propType.Name == "String") { //去掉转义符号 if (value.IndexOf("\\\"") > -1) { returnObj = value.Replace("\\\"", "\""); } else { returnObj = value; } } else { returnObj = ConvertTool.ChangeType(value, propType); } #endregion break; case SysType.Array: case SysType.Collection: case SysType.Generic: #region 数组处理 if (objValue.GetType() == propType) { returnObj = objValue; } else { Type[] argTypes = null; int len = ReflectTool.GetArgumentLength(ref propType, out argTypes); if (len == 1) // Table { if (value.Contains(":") && value.Contains("{")) { #region Json 嵌套处理,复杂数组处理。 MDataTable dt = MDataTable.CreateFrom(value);//, SchemaCreate.GetColumns(argTypes[0]) returnObj = dt.ToList(propType); dt = null; #endregion } else { #region 单纯的基础类型数组处理["xxx","xxx2","xx3"] List items = JsonSplit.SplitEscapeArray(value);//内部去掉转义符号 if (items == null) { return null; } returnObj = Activator.CreateInstance(propType, items.Count);//创建实例 Type objListType = returnObj.GetType(); bool isArray = sysType == SysType.Array; for (int i = 0; i < items.Count; i++) { MethodInfo method; if (isArray) { Object item = ConvertTool.ChangeType(items[i], propType.GetElementType());//Type.GetType(propType.FullName.Replace("[]", "") method = objListType.GetMethod("Set"); if (method != null) { method.Invoke(returnObj, new object[] { i, item }); } } else { Object item = ConvertTool.ChangeType(items[i], argTypes[0]); method = objListType.GetMethod("Add"); if (method == null) { method = objListType.GetMethod("Push"); } if (method != null) { method.Invoke(returnObj, new object[] { item }); } } } #endregion } } else if (len == 2) // row { MDataRow mRow = MDataRow.CreateFrom(objValue, argTypes[1]); returnObj = propType.Name.Contains("Dictionary") ? Activator.CreateInstance(propType, StringComparer.OrdinalIgnoreCase) : Activator.CreateInstance(propType); //Activator.CreateInstance(propType, mRow.Columns.Count);//创建实例 Type objListType = returnObj.GetType(); foreach (MDataCell mCell in mRow) { object mObj = GetValue(mCell.ToRow(), argTypes[1]); MethodInfo mi = objListType.GetMethod("Add"); mi.Invoke(returnObj, new object[] { mCell.ColumnName, mObj }); } mRow = null; } } #endregion break; case SysType.Custom://继续递归 MDataRow mr = null; if (objValue is MDataRow) { mr = objValue as MDataRow; } else { mr = new MDataRow(TableSchema.GetColumnByType(propType)); mr.LoadFrom(objValue); } returnObj = Activator.CreateInstance(propType); SetToEntity(ref returnObj, mr); mr = null; break; } return returnObj; } } }