#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
|
{
|
/// <summary>
|
/// 基础资料(DataDict)的数据访问层基类
|
/// </summary>
|
public class dalBaseDataDict : dalBase, IBridge_DataDict
|
{
|
/// <summary>
|
/// 检查数据是否存在
|
/// </summary>
|
/// <param name="keyValue">主键</param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 检查某个字段的值是否存在
|
/// </summary>
|
/// <param name="keyFieldName">字段名称</param>
|
/// <param name="keyValue">值</param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 删除一条记录
|
/// </summary>
|
/// <param name="keyValue">主键</param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 获取指定主键的数据
|
/// </summary>
|
/// <param name="key">主键</param>
|
/// <returns></returns>
|
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);
|
}
|
|
/// <summary>
|
/// 跟据表名取数据字典
|
/// </summary>
|
/// <param name="tableName">字典表名</param>
|
/// <returns></returns>
|
public virtual DataTable GetDataDictByTableName(string tableName)
|
{
|
if (string.IsNullOrEmpty(tableName)) throw new Exception("表名不能为空!");
|
|
return _Database.GetTable($"SELECT * FROM {tableName}", tableName);
|
}
|
|
/// <summary>
|
/// 跟据表名取数据字典
|
/// </summary>
|
/// <param name="tableName">字典表名</param>
|
/// <returns></returns>
|
public virtual DataTable GetDataDictBySql(string tableName)
|
{
|
if (string.IsNullOrEmpty(tableName))
|
throw new Exception("SQL不能为空!");
|
|
return _Database.GetTable(tableName);
|
}
|
|
|
/// <summary>
|
/// 获取参考数据(LookupEdit组件使用)
|
/// </summary>
|
/// <returns></returns>
|
public virtual DataTable GetLookupData()
|
{
|
if (_LookupSQL == "") return GetSummaryData();
|
|
return _Database.GetTable(_LookupSQL, _TableName);
|
}
|
|
/// <summary>
|
/// 获取服务器时间
|
/// </summary>
|
/// <returns></returns>
|
public DateTime GetServerTime()
|
{
|
return _Database.GetServerTime();
|
}
|
|
/// <summary>
|
/// 获取主表数据
|
/// </summary>
|
/// <returns></returns>
|
public virtual DataTable GetSummaryData()
|
{
|
AssertTableName();
|
return _Database.GetTable($"SELECT * FROM {_TableName}",
|
_TableName);
|
}
|
|
/// <summary>
|
/// 提交数据
|
/// </summary>
|
/// <param name="data">需要更新的数据集(只要在CreateSqlGenerator方法内指定表名与ORM对应关系,支持更新多张表)</param>
|
/// <returns></returns>
|
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);
|
}
|
}
|
|
/// <summary>
|
/// 提交数据的扩展方法
|
/// </summary>
|
/// <param name="data">需要更新的数据集(只要在CreateSqlGenerator方法内指定表名与ORM对应关系,支持更新多张表)</param>
|
/// <returns></returns>
|
public virtual SaveResultEx UpdateEx(DataSet data)
|
{
|
var success = Update(data); //调用预设的保存方法
|
|
//返回一个对象类型的操作报告
|
return new SaveResultEx
|
{
|
Result = success ? (int)ResultID.SUCCESS : (int)ResultID.FAILED,
|
PrimaryKey = _LastGeneratedKey
|
};
|
}
|
|
/// <summary>
|
/// 检查表名是否为空
|
/// </summary>
|
public void AssertTableName()
|
{
|
if (_TableName == string.Empty) throw new Exception("数据字典未指定表名!");
|
}
|
|
/// <summary>
|
/// 根据表名获取该表的SQL命令生成器
|
/// </summary>
|
/// <param name="tableName">表名</param>
|
/// <returns></returns>
|
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);
|
}
|
|
/// <summary>
|
/// 获取数据字典的流水号
|
/// </summary>
|
protected virtual string GetNumber(DbTransaction tran)
|
{
|
return string.Empty;
|
}
|
|
/// <summary>
|
/// 设置数据字典数据的流水号
|
/// </summary>
|
/// <param name="summary">主表,处理第一条记录</param>
|
/// <param name="docFieldName"></param>
|
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 成员变量定义
|
|
/// <summary>
|
/// 当前数据字典的ORM模型
|
/// </summary>
|
protected Type _ModelType;
|
|
/// <summary>
|
/// 字典表名
|
/// </summary>
|
protected string _TableName = string.Empty;
|
|
/// <summary>
|
/// 主键字段名
|
/// </summary>
|
protected string _KeyName = string.Empty;
|
|
/// <summary>
|
/// 最后一次生成的流水号号码
|
/// </summary>
|
protected string _LastGeneratedKey = string.Empty;
|
|
/// <summary>
|
/// 提交数据前去左右空格、全角转半角
|
/// </summary>
|
protected bool _ReplaceString = false;
|
|
/// <summary>
|
/// 用于Lookup使用的查询语句,返回编号及名称两列字段的数据
|
/// </summary>
|
protected string _LookupSQL = "";
|
|
#endregion
|
|
#region 属性定义
|
|
/// <summary>
|
/// 新增数据字典,由后台自动生成的主键值
|
/// </summary>
|
public string LastGeneratedKey
|
{
|
get => _LastGeneratedKey;
|
set => _LastGeneratedKey = value;
|
}
|
|
/// <summary>
|
/// 数据字典的表名
|
/// </summary>
|
public string TableName
|
{
|
get => _TableName;
|
set => _TableName = value;
|
}
|
|
/// <summary>
|
/// 指定数据字典的ORM模型,并分析模型的特性类,获取表名及主键
|
/// </summary>
|
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 构造器
|
|
/// <summary>
|
/// 设置为受保护的构造器,不允许外部实例化
|
/// </summary>
|
/// <param name="loginer">当前用户登录信息</param>
|
protected dalBaseDataDict(Loginer loginer)
|
: base(loginer)
|
{
|
}
|
|
/// <summary>
|
/// 构造器
|
/// </summary>
|
/// <param name="loginer">当前用户登录信息</param>
|
/// <param name="ORM">数据字典的ORM类</param>
|
public dalBaseDataDict(Loginer loginer, Type ORM)
|
: base(loginer)
|
{
|
this.ORM = ORM;
|
}
|
|
/// <summary>
|
/// 构造器
|
/// </summary>
|
/// <param name="loginer">当前用户登录信息</param>
|
/// <param name="ORM">数据字典的ORM类</param>
|
/// <param name="DBID">指定数据库,该模型所在的数据库</param>
|
public dalBaseDataDict(Loginer loginer, Type ORM, string DBID)
|
: base(loginer)
|
{
|
this.ORM = ORM;
|
if (loginer.DBID != DBID)
|
_Database = DatabaseProvider.GetDatabase(DBID);
|
}
|
|
/// <summary>
|
/// 构造器
|
/// </summary>
|
/// <param name="loginer">当前用户登录信息</param>
|
/// <param name="tableName">字典表名</param>
|
public dalBaseDataDict(Loginer loginer, string tableName)
|
: base(loginer)
|
{
|
_TableName = tableName;
|
}
|
|
/// <summary>
|
/// 构造器
|
/// </summary>
|
/// <param name="loginer">当前用户登录信息</param>
|
/// <param name="tableName">字典表名</param>
|
/// <param name="DBID">所在数据库</param>
|
public dalBaseDataDict(Loginer loginer, string tableName, string DBID)
|
: base(loginer)
|
{
|
_TableName = tableName;
|
if (loginer.DBID != DBID)
|
_Database = DatabaseProvider.GetDatabase(DBID);
|
}
|
|
#endregion
|
}
|
}
|