#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
}
}