tijian_tieying/web/cyqdata-master/Table/MDataCell.cs
2025-02-20 12:14:39 +08:00

586 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Data;
using System.Collections.Generic;
using CYQ.Data.SQL;
using System.ComponentModel;
using System.Data.SqlTypes;
using System.Collections;
using CYQ.Data.Tool;
namespace CYQ.Data.Table
{
/// <summary>
/// 单元结构的值
/// </summary>
internal partial class MCellValue
{
internal bool IsNull = true;
/// <summary>
/// 状态改变:0;未改,1;进行赋值操作[但值相同],2:赋值,值不同改变了
/// </summary>
internal int State = 0;
internal object Value = null;
}
/// <summary>
/// 单元格
/// </summary>
public partial class MDataCell
{
private MCellValue _CellValue;
private MCellValue CellValue
{
get
{
if (_CellValue == null)
{
_CellValue = new MCellValue();
}
return _CellValue;
}
}
private MCellStruct _CellStruct;
#region
/// <summary>
/// 原型模式Prototype Method
/// </summary>
/// <param name="dataStruct"></param>
internal MDataCell(ref MCellStruct dataStruct)
{
Init(dataStruct, null);
}
internal MDataCell(ref MCellStruct dataStruct, object value)
{
Init(dataStruct, value);
}
#endregion
#region
private void Init(MCellStruct dataStruct, object value)
{
_CellStruct = dataStruct;
if (value != null)
{
_CellValue = new MCellValue();
Value = value;
}
}
#endregion
#region
private string _StringValue = null;
/// <summary>
/// 字符串值
/// </summary>
public string StringValue
{
get
{
CheckNewValue();
return _StringValue;
}
internal set
{
_StringValue = value;
}
}
private object newValue = null;
private bool isNewValue = false;
/// <summary>
/// 值
/// </summary>
public object Value
{
get
{
CheckNewValue();
return CellValue.Value;
}
set
{
//只是赋值,值的检测延时到获取属性时触发
newValue = value;
isNewValue = true;
isAllowChangeState = true;
}
}
internal object SourceValue
{
set
{
CellValue.Value = value;
}
}
/// <summary>
/// 延时检测值的类型
/// </summary>
private void CheckNewValue()
{
if (isNewValue)
{
isNewValue = false;
FixValue(newValue);
newValue = null;
isAllowChangeState = true;//恢复可设置状态。
}
}
private void FixValue(object value)
{
#region CheckValue
bool valueIsNull = value == null || value == DBNull.Value;
if (valueIsNull)
{
if (CellValue.IsNull)
{
CellValue.State = (value == DBNull.Value) ? 2 : 1;
}
else
{
if (isAllowChangeState)
{
CellValue.State = 2;
}
CellValue.Value = null;
CellValue.IsNull = true;
StringValue = string.Empty;
}
}
else
{
StringValue = value.ToString();
int groupID = DataType.GetGroup(_CellStruct.SqlType);
if (_CellStruct.SqlType != SqlDbType.Variant)
{
if (StringValue == "" && groupID > 0)
{
CellValue.Value = null;
CellValue.IsNull = true;
return;
}
value = ChangeValue(value, _CellStruct.ValueType, groupID);
if (value == null)
{
return;
}
}
if (!CellValue.IsNull && (CellValue.Value.Equals(value) || (groupID != 999 && CellValue.Value.ToString() == StringValue)))//对象的比较值,用==号则比例引用地址。
{
if (isAllowChangeState)
{
CellValue.State = 1;
}
}
else
{
CellValue.Value = value;
CellValue.IsNull = false;
if (isAllowChangeState)
{
CellValue.State = 2;
}
}
}
#endregion
}
/// <summary>
/// 数据类型被切换,重新修正值的类型。
/// </summary>
public bool FixValue()
{
Exception err = null;
return FixValue(out err);
}
/// <summary>
/// 数据类型被切换,重新修正值的类型。
/// </summary>
public bool FixValue(out Exception ex)
{
ex = null;
if (!IsNull)
{
CellValue.Value = ChangeValue(CellValue.Value, _CellStruct.ValueType, DataType.GetGroup(_CellStruct.SqlType), out ex);
}
return ex == null;
}
internal object ChangeValue(object value, Type convertionType, int groupID)
{
Exception err;
return ChangeValue(value, convertionType, groupID, out err);
}
/// <summary>
/// 值的数据类型转换。
/// </summary>
/// <param name="value">要被转换的值</param>
/// <param name="convertionType">要转换成哪种类型</param>
/// <param name="groupID">数据库类型的组号</param>
/// <returns></returns>
internal object ChangeValue(object value, Type convertionType, int groupID, out Exception ex)
{
ex = null;
StringValue = Convert.ToString(value);
if (value == null)
{
CellValue.IsNull = true;
return value;
}
if (groupID > 0 && StringValue == "")
{
CellValue.IsNull = true;
return null;
}
try
{
#region
if (groupID == 1)
{
switch (StringValue)
{
case "正无穷大":
StringValue = "Infinity";
break;
case "负无穷大":
StringValue = "-Infinity";
break;
}
}
if (value.GetType() != convertionType)
{
#region
switch (groupID)
{
case 0:
if (_CellStruct.SqlType == SqlDbType.Time)//time类型的特殊处理。
{
string[] items = StringValue.Split(' ');
if (items.Length > 1)
{
StringValue = items[1];
}
}
value = StringValue;
break;
case 1:
switch (StringValue.ToLower())
{
case "true":
value = 1;
break;
case "false":
value = 0;
break;
case "infinity":
value = double.PositiveInfinity;
break;
case "-infinity":
value = double.NegativeInfinity;
break;
default:
goto err;
}
break;
case 2:
switch (StringValue.ToLower().TrimEnd(')', '('))
{
case "now":
case "getdate":
case "current_timestamp":
value = DateTime.Now;
break;
default:
DateTime dt = DateTime.Parse(StringValue);
value = dt == DateTime.MinValue ? (DateTime)SqlDateTime.MinValue : dt;
break;
}
break;
case 3:
switch (StringValue.ToLower())
{
case "yes":
case "true":
case "1":
case "on":
case "是":
value = true;
break;
case "no":
case "false":
case "0":
case "":
case "否":
default:
value = false;
break;
}
break;
case 4:
if (StringValue == SqlValue.Guid || StringValue.StartsWith("newid"))
{
value = Guid.NewGuid();
}
else
{
value = new Guid(StringValue);
}
break;
default:
err:
if (convertionType.Name.EndsWith("[]"))
{
value = Convert.FromBase64String(StringValue);
StringValue = "System.Byte[]";
}
else
{
value = StaticTool.ChangeType(value, convertionType);
}
break;
}
#endregion
}
//else if (groupID == 2 && strValue.StartsWith("000"))
//{
// value = SqlDateTime.MinValue;
//}
#endregion
}
catch (Exception err)
{
value = null;
CellValue.Value = null;
CellValue.IsNull = true;
ex = err;
string msg = string.Format("ChangeType ErrorColumnName【{0}】({1}) Value【{2}】\r\n", _CellStruct.ColumnName, _CellStruct.ValueType.FullName, StringValue);
StringValue = null;
if (AppConfig.Log.IsWriteLog)
{
Log.WriteLog(true, msg);
}
}
return value;
}
internal T Get<T>()
{
if (CellValue.IsNull)
{
return default(T);
}
Type t = typeof(T);
return (T)ChangeValue(CellValue.Value, t, DataType.GetGroup(DataType.GetSqlType(t)));
}
/// <summary>
/// 值是否为Null值[只读属性]
/// </summary>
public bool IsNull
{
get
{
CheckNewValue();
return CellValue.IsNull;
}
internal set
{
CellValue.IsNull = value;
}
}
/// <summary>
/// 值是否为Null或为空[只读属性]
/// </summary>
public bool IsNullOrEmpty
{
get
{
CheckNewValue();
return CellValue.IsNull || StringValue.Length == 0;
}
}
/// <summary>
/// 列名[只读属性]
/// </summary>
public string ColumnName
{
get
{
return _CellStruct.ColumnName;
}
}
/// <summary>
/// 单元格的结构
/// </summary>
public MCellStruct Struct
{
get
{
return _CellStruct;
}
}
private bool isAllowChangeState = true;
/// <summary>
/// Value的状态:0;未改,1;进行赋值操作[但值相同],2:赋值,值不同改变了
/// </summary>
public int State
{
get
{
CheckNewValue();
return CellValue.State;
}
set
{
//如果设值(延时加载),又设置状态(在获取时设置的状态会失效)
if (isNewValue) { isAllowChangeState = false; }
CellValue.State = value;
}
}
#endregion
#region
/// <summary>
/// 将值重置为空
/// </summary>
public void Clear()
{
isNewValue = false;
newValue = null;
CellValue.Value = null;
CellValue.State = 0;
CellValue.IsNull = true;
StringValue = null;
}
internal void LoadValue(MDataCell cell)
{
StringValue = cell.StringValue;
CellValue.Value = cell.Value;
CellValue.State = cell.State;
CellValue.IsNull = cell.IsNull;
}
/// <summary>
/// 设置默认值。
/// </summary>
internal void SetDefaultValueToValue()
{
if (Convert.ToString(_CellStruct.DefaultValue).Length > 0)
{
switch (DataType.GetGroup(_CellStruct.SqlType))
{
case 2:
Value = DateTime.Now;
break;
case 4:
if (_CellStruct.DefaultValue.ToString().Length == 36)
{
Value = new Guid(_CellStruct.DefaultValue.ToString());
}
else
{
Value = Guid.NewGuid();
}
break;
default:
Value = _CellStruct.DefaultValue;
break;
}
}
}
/// <summary>
/// 已被重载默认返回Value值。
/// </summary>
/// <returns></returns>
public override string ToString()
{
return StringValue ?? "";
}
/// <summary>
/// 是否值相同[已重写该方法]
/// </summary>
public override bool Equals(object value)
{
bool valueIsNull = (value == null || value == DBNull.Value);
if (CellValue.IsNull)
{
return valueIsNull;
}
if (valueIsNull)
{
return CellValue.IsNull;
}
return StringValue.ToLower() == Convert.ToString(value).ToLower();
}
/// <summary>
/// 转成行
/// </summary>
internal MDataRow ToRow()
{
MDataRow row = new MDataRow();
row.Add(this);
return row;
}
#endregion
}
//扩展交互部分
public partial class MDataCell
{
internal string ToXml(bool isConvertNameToLower)
{
string text = StringValue??"";
switch (DataType.GetGroup(_CellStruct.SqlType))
{
case 999:
MDataRow row = null;
MDataTable table = null;
Type t = Value.GetType();
if (!t.FullName.StartsWith("System."))//普通对象。
{
row = new MDataRow(TableSchema.GetColumns(t));
row.LoadFrom(Value);
}
else if (Value is IEnumerable)
{
int len = StaticTool.GetArgumentLength(ref t);
if (len == 1)
{
table = MDataTable.CreateFrom(Value);
}
else if (len == 2)
{
row = MDataRow.CreateFrom(Value);
}
}
if (row != null)
{
text = row.ToXml(isConvertNameToLower);
}
else if (table != null)
{
text = string.Empty;
foreach (MDataRow r in table.Rows)
{
text += r.ToXml(isConvertNameToLower);
}
text += "\r\n ";
}
return string.Format("\r\n <{0}>{1}</{0}>", isConvertNameToLower ? ColumnName.ToLower() : ColumnName, text);
default:
if (text.LastIndexOfAny(new char[] { '<', '>', '&' }) > -1 && !text.StartsWith("<![CDATA["))
{
text = "<![CDATA[" + text.Trim() + "]]>";
}
return string.Format("\r\n <{0}>{1}</{0}>", isConvertNameToLower ? ColumnName.ToLower() : ColumnName, text);
}
}
}
}