#region using System; using System.Data; using System.Data.Common; using CSFrameworkV5.Common; using CSFrameworkV5.Core; using CSFrameworkV5.Core.CodeGenerator; using CSFrameworkV5.Interfaces; #endregion namespace CSFrameworkV5.DataAccess { /// /// 基础资料(DataDict)的数据访问层基类 /// public class dalBaseDataDict : dalBase, IBridge_DataDict { /// /// 检查数据是否存在 /// /// 主键 /// public virtual bool CheckNoExists(string keyValue) { var sql = $"SELECT COUNT(*) C FROM {_TableName} WHERE {_KeyName}={_Database.ParamSymboName}KEY"; var cmd = _Database.CreateCommand(sql); cmd.AddParam("KEY", DbType.String, keyValue); var o = _Database.ExecuteScalar(cmd.Command); return ConvertEx.ToInt(o) > 0; } /// /// 检查某个字段的值是否存在 /// /// 字段名称 /// 值 /// public virtual bool CheckNoExists(string keyFieldName, string keyValue) { var sql = $"SELECT COUNT(*) C FROM {_TableName} WHERE {keyFieldName}={_Database.ParamSymboName}KEY"; var cmd = _Database.CreateCommand(sql); cmd.AddParam("KEY", DbType.String, keyValue); var o = _Database.ExecuteScalar(cmd.Command); return ConvertEx.ToInt(o) > 0; } /// /// 删除一条记录 /// /// 主键 /// public virtual bool Delete(string keyValue) { var sql = $"DELETE FROM {_TableName} WHERE {_KeyName}={_Database.ParamSymboName}KEY"; var cmd = _Database.CreateCommand(sql); cmd.AddParam("KEY", DbType.String, keyValue); var i = _Database.ExecuteCommand(cmd.Command); return i != 0; } /// /// 获取指定主键的数据 /// /// 主键 /// public virtual DataTable GetDataByKey(string key) { var sql = $"SELECT * FROM {_TableName} WHERE {_KeyName}={_Database.ParamSymboName}KEY"; var cmd = _Database.CreateCommand(sql); cmd.AddParam("KEY", DbType.String, key); return _Database.GetTable(cmd.Command, _TableName); } /// /// 跟据表名取数据字典 /// /// 字典表名 /// public virtual DataTable GetDataDictByTableName(string tableName) { if (string.IsNullOrEmpty(tableName)) throw new Exception("表名不能为空!"); return _Database.GetTable($"SELECT * FROM {tableName}", tableName); } /// /// 跟据表名取数据字典 /// /// 字典表名 /// public virtual DataTable GetDataDictBySql(string tableName) { if (string.IsNullOrEmpty(tableName)) throw new Exception("SQL不能为空!"); return _Database.GetTable(tableName); } /// /// 获取参考数据(LookupEdit组件使用) /// /// public virtual DataTable GetLookupData() { if (_LookupSQL == "") return GetSummaryData(); return _Database.GetTable(_LookupSQL, _TableName); } /// /// 获取服务器时间 /// /// public DateTime GetServerTime() { return _Database.GetServerTime(); } /// /// 获取主表数据 /// /// public virtual DataTable GetSummaryData() { AssertTableName(); return _Database.GetTable($"SELECT * FROM {_TableName}", _TableName); } /// /// 提交数据 /// /// 需要更新的数据集(只要在CreateSqlGenerator方法内指定表名与ORM对应关系,支持更新多张表) /// public virtual bool Update(DataSet data) { _CurrentDataSet4Update = data; //非用户手动事务模式,预设启用事务 if (_UserManualControlTrans == false) BeginTransaction(); if (_CurrentTrans == null) throw new Exception("用户手动控制事务模式下,但您没有启用事务!"); try { foreach (DataTable dt in data.Tables) { _CurrentTable4Update = dt; if (dt.GetChanges() == null) continue; //没有数据更新 if (_ReplaceString) FieldFitString.FitString(dt); var gen = CreateSqlGenerator(dt); if (gen == null) throw new CustomException("创建SQL命令生成器失败!表名:" + dt.TableName); //如果表有定义流水号字段,自动生成流水号码 var docFieldName = gen.GetDocNoFieldName(); if (!string.IsNullOrEmpty(docFieldName)) SetDataSN(dt, docFieldName); var adp = _Database.CreateDataAdapter(AdapterRowUpdatingEvent); adp.UpdateCommand = gen.GetUpdateCommand(_CurrentTrans); adp.InsertCommand = gen.GetInsertCommand(_CurrentTrans); adp.DeleteCommand = gen.GetDeleteCommand(_CurrentTrans); adp.AcceptChangesDuringUpdate = false; //提交数据后保留原始数据,用于保存修改日志,对比原始值2017-02-26 adp.Update(dt); adp.Dispose(); } if (_UserManualControlTrans == false) CommitTransaction(); //提交事务 return true; } catch (DBConcurrencyException ex) { if (_UserManualControlTrans == false) RollbackTransaction(); //回滚事务 throw new Exception( "并发操作!其他用户已更新了源数据!Event:DAL.Update()\r\n\r\n" + ex.Message); } catch (Exception ex) { if (_UserManualControlTrans == false) RollbackTransaction(); //回滚事务 throw new Exception("更新数据发生错误!Event:DAL.Update()\r\n\r\n" + ex.Message); } } /// /// 提交数据的扩展方法 /// /// 需要更新的数据集(只要在CreateSqlGenerator方法内指定表名与ORM对应关系,支持更新多张表) /// public virtual SaveResultEx UpdateEx(DataSet data) { var success = Update(data); //调用预设的保存方法 //返回一个对象类型的操作报告 return new SaveResultEx { Result = success ? (int)ResultID.SUCCESS : (int)ResultID.FAILED, PrimaryKey = _LastGeneratedKey }; } /// /// 检查表名是否为空 /// public void AssertTableName() { if (_TableName == string.Empty) throw new Exception("数据字典未指定表名!"); } /// /// 根据表名获取该表的SQL命令生成器 /// /// 表名 /// protected virtual IGenerateSqlCommand CreateSqlGenerator( DataTable table) { if (_ModelType == null) throw new Exception("没绑定数据表结构定义!"); if (table.TableName == _TableName) return new GenerateSqlCmdByTableFields(_ModelType, table, GeneratorFactory); throw new Exception("创建IGenerateSqlCommand失败!"); //支持两种SQL命令生成器 //IGenerateSqlCommand gen = new GenerateSqlCmdByObjectClass(_ModelType, _Database); } /// /// 获取数据字典的流水号 /// protected virtual string GetNumber(DbTransaction tran) { return string.Empty; } /// /// 设置数据字典数据的流水号 /// /// 主表,处理第一条记录 /// private void SetDataSN(DataTable summary, string docFieldName) { var row = summary.Rows[0]; //取第一条记录 //如果未指定流水号更新类型则取旧的流水号. if (row.RowState == DataRowState.Modified || _UpdateSummaryKeyMode == UpdateKeyMode.None) //取旧的单号 _LastGeneratedKey = row[docFieldName].ToStringEx(); //新增记录,更新主键的值 if (row.RowState == DataRowState.Added) { //注意状态的使用,只有在新增状态下才更新单号 if (_UpdateSummaryKeyMode == UpdateKeyMode.OnlyGuid) { if (docFieldName == "") throw new Exception("没有设定流水号字段,检查类模型参数定义!"); _LastGeneratedKey = Guid.NewGuid().ToStringEx().Replace("-", ""); row[docFieldName] = _LastGeneratedKey; } if (_UpdateSummaryKeyMode == UpdateKeyMode.OnlyDocumentNo) { if (docFieldName == "") throw new Exception("没有设定流水号字段,检查类模型参数定义!"); _LastGeneratedKey = GetNumber(_CurrentTrans); //调用模板方法获取流水号码 row[docFieldName] = _LastGeneratedKey; } } } #region 成员变量定义 /// /// 当前数据字典的ORM模型 /// protected Type _ModelType; /// /// 字典表名 /// protected string _TableName = string.Empty; /// /// 主键字段名 /// protected string _KeyName = string.Empty; /// /// 最后一次生成的流水号号码 /// protected string _LastGeneratedKey = string.Empty; /// /// 提交数据前去左右空格、全角转半角 /// protected bool _ReplaceString = false; /// /// 用于Lookup使用的查询语句,返回编号及名称两列字段的数据 /// protected string _LookupSQL = ""; #endregion #region 属性定义 /// /// 新增数据字典,由后台自动生成的主键值 /// public string LastGeneratedKey { get => _LastGeneratedKey; set => _LastGeneratedKey = value; } /// /// 数据字典的表名 /// public string TableName { get => _TableName; set => _TableName = value; } /// /// 指定数据字典的ORM模型,并分析模型的特性类,获取表名及主键 /// public Type ORM { get => _ModelType; set { _ModelType = value; if (_ModelType == null) throw new Exception("ORM为能为null!"); //分析模型类的特性 var attrs = _ModelType.GetCustomAttributes(typeof(ORM_TableAttribute), false); if (attrs.Length == 0) throw new Exception("ORM模型没定义ORM_ObjectClassAttribute属性!"); //获取表名及主键 _TableName = (attrs[0] as ORM_TableAttribute).TableName; _KeyName = (attrs[0] as ORM_TableAttribute).PrimaryKey; } } #endregion #region dalBaseDataDict 构造器 /// /// 设置为受保护的构造器,不允许外部实例化 /// /// 当前用户登录信息 protected dalBaseDataDict(Loginer loginer) : base(loginer) { } /// /// 构造器 /// /// 当前用户登录信息 /// 数据字典的ORM类 public dalBaseDataDict(Loginer loginer, Type ORM) : base(loginer) { this.ORM = ORM; } /// /// 构造器 /// /// 当前用户登录信息 /// 数据字典的ORM类 /// 指定数据库,该模型所在的数据库 public dalBaseDataDict(Loginer loginer, Type ORM, string DBID) : base(loginer) { this.ORM = ORM; if (loginer.DBID != DBID) _Database = DatabaseProvider.GetDatabase(DBID); } /// /// 构造器 /// /// 当前用户登录信息 /// 字典表名 public dalBaseDataDict(Loginer loginer, string tableName) : base(loginer) { _TableName = tableName; } /// /// 构造器 /// /// 当前用户登录信息 /// 字典表名 /// 所在数据库 public dalBaseDataDict(Loginer loginer, string tableName, string DBID) : base(loginer) { _TableName = tableName; if (loginer.DBID != DBID) _Database = DatabaseProvider.GetDatabase(DBID); } #endregion } }