using CYQ.Data.SQL; using System.Data.SqlClient; using System.Data; using System; using CYQ.Data.Table; using CYQ.Data.Aop; using System.Collections.Generic; using CYQ.Data.Tool; using System.Data.Common; using CYQ.Data.Json; namespace CYQ.Data { /// /// Manipulate:sql / procedure ///操作:SQL或存储过程 /// public class MProc : IDisposable { #region 隐式转换 /// /// Change MAction to MProc /// 将一个MAction 转换成一个MProc。 /// public static implicit operator MProc(MAction action) { return new MProc(action.dalHelper); } public static implicit operator MProc(Orm.SimpleOrmBase orm) { if (orm.Action != null) { return new MProc(orm.Action.dalHelper); } return null; } public static implicit operator MProc(Orm.OrmBase orm) { if (orm.Action != null) { return new MProc(orm.Action.dalHelper); } return null; } #endregion internal DalBase dalHelper; private InterAop _aop = new InterAop(); private string _procName = string.Empty; private bool _isProc = true; private string _debugInfo = string.Empty; /// /// Get or set debugging information [need to set App Config.Debug.Open DebugInfo to ture] ///获取或设置调试信息[需要设置AppConfig.Debug.OpenDebugInfo为ture] /// public string DebugInfo { get { if (dalHelper != null) { return dalHelper.DebugInfo.ToString(); } return _debugInfo; } } /// /// The database type /// 数据库类型 /// public DataBaseType DataBaseType { get { if (dalHelper != null) { return dalHelper.DataBaseType; } return AppConfig.DB.DefaultDataBaseType; } } /// /// The database name /// 数据库名称 /// public string DataBaseName { get { if (dalHelper != null) { return dalHelper.DataBaseName; } return AppConfig.DB.DefaultDataBaseName; } } /// /// The database version /// 数据库的版本号 /// public string DataBaseVersion { get { if (dalHelper != null) { return dalHelper.Version; } return ""; } } /// /// The number of rows affected when executing a SQL command (-2 is an exception) /// 执行SQL命令时受影响的行数(-2则为异常)。 /// public int RecordsAffected { get { if (dalHelper != null) { return dalHelper.RecordsAffected; } return 0; } } /// /// 是否事务进行中 /// public bool IsTransation { get { return dalHelper.IsOpenTrans; } } /// /// The database connection string ///数据库链接字符串 /// public string ConnString { get { if (dalHelper != null && dalHelper.Con != null) { return dalHelper.UsingConnBean.ConnStringOrg; } return string.Empty; } } /// /// The database connection name ///数据库链接配置名称 /// public string ConnName { get { if (dalHelper != null && dalHelper.Con != null) { return dalHelper.UsingConnBean.ConnName; } return string.Empty; } } /// /// Command Timeout[seconds] ///命令超时设置[单位秒] /// public int TimeOut { get { if (dalHelper != null && dalHelper.Com != null) { return dalHelper.Com.CommandTimeout; } return -1; } set { if (dalHelper != null && dalHelper.Com != null) { dalHelper.Com.CommandTimeout = value; } } } /// /// Instantiation /// 实例化 /// /// Parameters: sql or procedure /// 参数:SQL语句或存储过程名称 public MProc(object procNameOrSql) { Init(procNameOrSql, null, false); } public MProc(object procNameOrSql, string conn) { Init(procNameOrSql, conn, false); } internal MProc(DalBase dalBase) { _procName = string.Empty; SetDalBase(dalBase, false); } private void Init(object procNameOrSql, string conn, bool isClearPara) { #region 分析是Sql或者存储过程 if (procNameOrSql != null) { if (string.IsNullOrEmpty(conn)) { if (procNameOrSql is Enum) { conn = CrossDB.GetConnByEnum(procNameOrSql as Enum); } if (string.IsNullOrEmpty(conn) && !string.IsNullOrEmpty(ConnName)) { conn = ConnName; } } if (procNameOrSql is String) { string fixName; conn = CrossDB.GetConn(procNameOrSql.ToString(), out fixName, conn); } _procName = procNameOrSql.ToString().Trim(); _isProc = _procName.IndexOf(' ') == -1;//不包含空格 if (string.IsNullOrEmpty(conn) && dalHelper == null) { conn = AppConfig.DB.DefaultConn; } } #endregion DalBase dalBase = null; if (conn != null && dalHelper == null) { dalBase = DalCreate.CreateDal(conn); } SetDalBase(dalBase, isClearPara); } private void SetDalBase(DalBase dalBase, bool isClearPara) { if (dalHelper == null && dalBase != null) { dalHelper = dalBase; if (dalHelper.IsOnExceptionEventNull) { dalHelper.OnExceptionEvent += new DalBase.OnException(helper_OnExceptionEvent); } } else if (isClearPara && dalHelper != null) { dalHelper.ClearParameters(); } } /// /// IsClearParameters /// 是否清除参数 /// public void ResetProc(object procNameOrSql, bool isClearPara) { Init(procNameOrSql, null, isClearPara); } /// /// Toggle tProc Action: To switch between other sql/procedure, use this method /// 切换操作:如需操作其它语句或存储过程,通过此方法切换 /// /// Parameters: sql or procedure /// 参数:存储过程名或Sql语句 public void ResetProc(object procNameOrSql) { ResetProc(procNameOrSql, true); } private AopResult SetAopResult(AopEnum action) { if (_aop.IsLoadAop) { _aop.Para.MProc = this; _aop.Para.ProcName = _procName; _aop.Para.IsProc = _isProc; if (dalHelper.Com != null) { _aop.Para.DBParameters = dalHelper.Com.Parameters; } _aop.Para.IsTransaction = dalHelper.IsOpenTrans; return _aop.Begin(action); } return AopResult.Default; } /// /// Get MDataTable /// public MDataTable ExeMDataTable() { CheckDisposed(); AopResult aopResult = SetAopResult(AopEnum.ExeMDataTable); if (aopResult == AopResult.Return) { return _aop.Para.Table; } else { if (aopResult != AopResult.Break) { _aop.Para.Table = dalHelper.ExeDataReader(_procName, _isProc); _aop.Para.Table.Columns.DataBaseType = DataBaseType; _aop.Para.Table.Conn = dalHelper.ConnName; _aop.Para.IsSuccess = _aop.Para.Table.Rows.Count > 0; } if (aopResult != AopResult.Default) { _aop.End(AopEnum.ExeMDataTable); } return _aop.Para.Table; } } /// /// 执行并返回泛型列表类型。 /// public List ExeList() where T : class { CheckDisposed(); List list; AopResult aopResult = SetAopResult(AopEnum.ExeList); if (aopResult == AopResult.Return) { object cacheObj = _aop.Para.ExeResult; if (cacheObj is String) { return JsonHelper.ToList(cacheObj.ToString(), EscapeOp.Encode); } return _aop.Para.ExeResult as List; } else { if (aopResult != AopResult.Break) { list = ConvertTool.ChangeReaderToList(dalHelper.ExeDataReader(_procName, _isProc)); _aop.Para.ExeResult = list; _aop.Para.IsSuccess = list.Count > 0; } if (aopResult != AopResult.Default) { _aop.End(AopEnum.ExeList); } return _aop.Para.ExeResult as List; } } /// /// 执行列表数据并返回Json格式字符串。 /// public string ExeJson() { return ExeJson(false, null); } public string ExeJson(bool isConvertNameToLower) { return ExeJson(isConvertNameToLower, null); } /// /// 执行列表数据并返回Json格式字符串。 /// /// 字段是否返回小写 /// 是否需要格式化时间,默认:yyyy-MM-dd HH:mm:ss /// public string ExeJson(bool isConvertNameToLower, string dateTimeFormatter) { CheckDisposed(); string json; AopResult aopResult = SetAopResult(AopEnum.ExeJson); if (aopResult == AopResult.Return) { object cacheObj = _aop.Para.ExeResult; return cacheObj as string; } else { if (aopResult != AopResult.Break) { JsonHelper js = new JsonHelper(false, false); js.IsConvertNameToLower = isConvertNameToLower; if (!string.IsNullOrEmpty(dateTimeFormatter)) { js.DateTimeFormatter = dateTimeFormatter; } json = ConvertTool.ChangeReaderToJson(dalHelper.ExeDataReader(_procName, _isProc), js, false); _aop.Para.ExeResult = json; _aop.Para.IsSuccess = json.Length > 4; } if (aopResult != AopResult.Default) { _aop.End(AopEnum.ExeJson); } return JsonHelper.ToJson(_aop.Para.ExeResult); } } /// /// Get MDataTables /// public List ExeMDataTableList() { CheckDisposed(); AopResult aopResult = SetAopResult(AopEnum.ExeMDataTableList); if (aopResult == AopResult.Return) { return _aop.Para.TableList; } else { if (aopResult != AopResult.Break) { List dtList = new List(); switch (dalHelper.DataBaseType) { case DataBaseType.Txt: case DataBaseType.Xml: case DataBaseType.Oracle: if (_isProc && dalHelper.DataBaseType == DataBaseType.Oracle) { goto isProc; } foreach (string sql in _procName.TrimEnd(';').Split(';')) { MDataTable dt = dalHelper.ExeDataReader(sql, false); if (dt != null) { dtList.Add(dt); } } break; default: isProc: DbDataReader reader = dalHelper.ExeDataReader(_procName, _isProc); if (reader != null) { do { dtList.Add(MDataTable.CreateFrom(reader)); } while (reader.NextResult()); reader.Close(); reader.Dispose(); reader = null; } break; } _aop.Para.TableList = dtList; _aop.Para.IsSuccess = dtList.Count > 0; } if (aopResult != AopResult.Default) { _aop.End(AopEnum.ExeMDataTableList); } return _aop.Para.TableList; } } /// /// Returns the number of rows affected [used to insert update or delete], and returns -2 if an exception is executed /// 返回受影响的行数[用于更新或删除],执行异常时返回-2 /// public int ExeNonQuery() { CheckDisposed(); AopResult aopResult = SetAopResult(AopEnum.ExeNonQuery); if (aopResult == AopResult.Return && _aop.Para.ExeResult is int) { return (int)_aop.Para.ExeResult; } else { if (aopResult != AopResult.Break) { int result = dalHelper.ExeNonQuery(_procName, _isProc); _aop.Para.ExeResult = result; _aop.Para.IsSuccess = result > 0; } if (aopResult != AopResult.Default) { _aop.End(AopEnum.ExeNonQuery); } return (int)_aop.Para.ExeResult; } } /// /// Returns the value of the first column of the first row /// 返回首行首列的值 /// public T ExeScalar() { CheckDisposed(); AopResult aopResult = SetAopResult(AopEnum.ExeScalar); if (aopResult == AopResult.Default || aopResult == AopResult.Continue) { _aop.Para.ExeResult = dalHelper.ExeScalar(_procName, _isProc); _aop.Para.IsSuccess = _aop.Para.ExeResult != null; } if (aopResult == AopResult.Continue || aopResult == AopResult.Break) { _aop.End(AopEnum.ExeScalar); } if (_aop.Para.ExeResult == null || _aop.Para.ExeResult == DBNull.Value) { return default(T); } return (T)ConvertTool.ChangeType(_aop.Para.ExeResult, typeof(T)); //Type t = typeof(T); //object value = _aop.Para.ExeResult; //switch (t.Name) //{ // case "Int32": // int intValue = 0; // if (!int.TryParse(Convert.ToString(value), out intValue)) // { // return default(T); // } // value = intValue; // break; // default: // try // { // value = ConvertTool.ChangeType(value, t); //} //catch //{ //} //break; //} //return (T)value; } /// /// Set Input Para /// 设置存储过程Input参数 /// public MProc Set(object paraName, object value) { dalHelper.AddParameters(Convert.ToString(paraName), value); return this; } public MProc Set(object paraName, object value, DbType dbType) { dalHelper.AddParameters(Convert.ToString(paraName), value, dbType, -1, ParameterDirection.Input); return this; } /// /// 设置特殊自定义参数 /// public MProc SetCustom(object paraName, ParaType paraType) { return SetCustom(paraName, paraType, null, null); } /// /// Set the stored procedure OutPut, the return value and other special types of parameters /// 设置存储过程OutPut、返回值等特殊类型参数 /// public MProc SetCustom(object paraName, ParaType paraType, object value) { return SetCustom(paraName, paraType, value, null); } /// MSSQL The name of the user-defined table typeMSSQL的用户定义表类型的名称 public MProc SetCustom(object paraName, ParaType paraType, object value, string typeName) { dalHelper.AddCustomePara(Convert.ToString(paraName), paraType, value, typeName); return this; } /// /// Clear Parameters /// 清除存储过程参数 /// public void Clear() { dalHelper.ClearParameters(); } /// /// Get Procedure Return Value /// 存储过程的返回值 /// public int ReturnValue { get { return dalHelper.ReturnValue; } } /// /// The OutPut value for the stored procedure: Dictionary for multiple values /// 存储过程的OutPut值:多个值时为Dictionary /// public object OutPutValue { get { return dalHelper.OutPutValue; } } #region Aop 相关操作 /// /// 获取或设置当前操作是否使用自动缓存 /// public bool IsUseAutoCache { get { return AppConfig.AutoCache.IsEnable && (_aop.aopOp == AopOp.OpenAll || _aop.aopOp == AopOp.OnlyInner); } set { switch (_aop.aopOp) { case AopOp.CloseAll: _aop.aopOp = value ? AopOp.OnlyInner : AopOp.CloseAll; break; case AopOp.OnlyInner: _aop.aopOp = value ? AopOp.OnlyInner : AopOp.CloseAll; break; case AopOp.OnlyOuter: _aop.aopOp = value ? AopOp.OpenAll : AopOp.OnlyOuter; break; case AopOp.OpenAll: _aop.aopOp = value ? AopOp.OpenAll : AopOp.OnlyOuter; break; } } } /// /// Set Aop State /// 设置Aop状态 /// public MProc SetAopState(AopOp op) { _aop.aopOp = op; return this; } /// /// Pass additional parameters for Aop use /// 传递额外的参数供Aop使用 /// public MProc SetAopPara(object para) { _aop.Para.AopPara = para; return this; } void helper_OnExceptionEvent(string errorMsg) { _aop.OnError(errorMsg); } #endregion #region 事务操作 /// /// Set the transaction level /// 设置事务级别 /// /// IsolationLevel public MProc SetTransLevel(IsolationLevel level) { dalHelper.TranLevel = level; return this; } /// /// Begin Transation /// 开始事务 /// public void BeginTransation() { dalHelper.IsOpenTrans = true; } /// /// Commit Transation /// 提交事务 /// public bool EndTransation() { if (dalHelper != null && dalHelper.IsOpenTrans) { return dalHelper.EndTransaction(); } return false; } /// /// RollBack Transation /// 事务回滚 /// public bool RollBack() { if (dalHelper != null && dalHelper.IsOpenTrans) { return dalHelper.RollBack(); } return false; } #endregion #region IDisposable 成员 /// /// Dispose /// 释放资源 /// public void Dispose() { hasDisposed = true; if (dalHelper != null) { if (!dalHelper.IsOnExceptionEventNull) { dalHelper.OnExceptionEvent -= new DalBase.OnException(helper_OnExceptionEvent); } _debugInfo = dalHelper.DebugInfo.ToString(); dalHelper.Dispose(); dalHelper = null; } } bool hasDisposed = false; private void CheckDisposed() { if (hasDisposed) { Error.Throw("The current object 'MProc' has been disposed"); } } #endregion } }