using Newtonsoft.Json; using SKMC.Api.Common.File; using SKMC.Api.Common.Logger; using SqlSugar; using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Linq.Expressions; using System.Text; using DbType = SqlSugar.DbType; namespace SKMC.Api.Common.DB { /// /// SqlSugar的工具类 /// public class SqlSugarTool { private static readonly ILogger log = LogFactory.Get(); private static readonly AppConfig appConfig = AppConfig.Instance(); /// /// 从配置库文件获取数据库实例 /// /// public static SqlSugarClient GetConfigDB() => GetDB("DB_CONFIG"); /// /// 从运行库文件获取数据库实例 /// /// public static SqlSugarClient GetRuntimeDB() => GetDB("DB_RUNDATA"); private static SqlSugarClient GetDB(string dbName) { SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = String.Format(appConfig.ReadStringValue(dbName, "connection.datasource"), System.Environment.CurrentDirectory), DbType = DbType.Sqlite, // 自动释放数据务,如果存在事务,在事务结束后释放 IsAutoCloseConnection = appConfig.ReadBoolValue(dbName, "connection.autoclosed"), // 从数据库系统表读取主键信息中(InitKeyType.Attribute从实体特性中读取主键自增列信息) InitKeyType = InitKeyType.Attribute // 暂不设置数据库缓存 }); // 调试SQL,AOP ,日志 db.Aop.OnLogExecuted = (sql, pars) => // SQL执行完事件 { // 获取执行后的总毫秒数 double sqlExecutionTotalMilliseconds = db.Ado.SqlExecutionTime.TotalMilliseconds; }; db.Aop.OnLogExecuting = (sql, pars) => // SQL执行前事件。可在这里查看生成的sql { string tempSQL = LookSQL(sql, pars); }; db.Aop.OnError = (exp) =>// 执行SQL 错误事件 { // exp.sql exp.parameters 可以拿到参数和错误Sql StringBuilder sb_SugarParameterStr = new StringBuilder("###SugarParameter参数为:"); var parametres = exp.Parametres as SugarParameter[]; if (parametres != null) { sb_SugarParameterStr.Append(JsonConvert.SerializeObject(parametres)); } StringBuilder sb_error = new StringBuilder(); sb_error.AppendLine("SqlSugarClient执行sql异常信息:" + exp.Message); sb_error.AppendLine("###赋值后sql:" + LookSQL(exp.Sql, parametres)); sb_error.AppendLine("###带参数的sql:" + exp.Sql); sb_error.AppendLine("###参数信息:" + sb_SugarParameterStr.ToString()); sb_error.AppendLine("###StackTrace信息:" + exp.StackTrace); log.Error(sb_error.ToString()); }; db.Aop.OnExecutingChangeSql = (sql, pars) => // SQL执行前 可以修改SQL { // 判断update或delete方法是否有where条件。如果真的想删除所有数据,请where(p=>true)或where(p=>p.id>0) if (sql.TrimStart().IndexOf("delete ", StringComparison.CurrentCultureIgnoreCase) == 0) { if (sql.IndexOf("where", StringComparison.CurrentCultureIgnoreCase) <= 0) { throw new Exception("delete删除方法需要有where条件!!"); } } else if (sql.TrimStart().IndexOf("update ", StringComparison.CurrentCultureIgnoreCase) == 0) { if (sql.IndexOf("where", StringComparison.CurrentCultureIgnoreCase) <= 0) { throw new Exception("update更新方法需要有where条件!!"); } } return new KeyValuePair(sql, pars); }; // db.Aop.OnDiffLogEvent = it =>// 数据库操作前和操作后的数据变化。 // { // var editBeforeData = it.BeforeData; // var editAfterData = it.AfterData; // var sql = it.Sql; // var parameter = it.Parameters; // var data = it.BusinessData; // var time = it.Time; // var diffType = it.DiffType;// 枚举值 insert 、update 和 delete 用来作业务区分 // 日志方法 // }; // db.Ado.CommandTimeOut // 设置sql执行超时等待时间(毫秒单位) // db.Ado.Connection.ConnectionTimeout // 设置数据库连接等待时间(毫秒单位) return db; } /// ///查看赋值后的sql /// /// ///参数 /// private static string LookSQL(string sql, SugarParameter[] pars) { if (pars == null || pars.Length == 0) return sql; StringBuilder sb_sql = new StringBuilder(sql); var tempOrderPars = pars.Where(p => p.Value != null).OrderByDescending(p => p.ParameterName.Length).ToList();// 防止 @par1错误替换@par12 for (var index = 0; index < tempOrderPars.Count; index++) { sb_sql.Replace(tempOrderPars[index].ParameterName, "'" + tempOrderPars[index].Value.ToString() + "'"); } return sb_sql.ToString(); } /// /// 获取一个实体 /// /// /// 主键 /// /// public static T GetModel(object id, SqlSugarClient db) { return db.Queryable().InSingle(id); } /// /// 从缓存中获取一个实体 /// /// /// 主键 /// /// public static T GetModel_WithCache(object id, SqlSugarClient db) { return db.Queryable().WithCache().InSingle(id); } /// /// 添加实体数据,并返回主键值(主键为自增int类型id,实体需要设置主键特性)(为null字段不更新,注意model有默认值的情况) /// /// /// /// (事务的db对象) /// public static int InsertModel(T t, SqlSugarClient db) where T : class, new() { // Where(true/*不插入null值的列*/,false/*不插入主键值*/) return db.Insertable(t). // IgnoreColumns(p=>p.Equals("id",StringComparison.InvariantCultureIgnoreCase)). IgnoreColumns(true, false).ExecuteReturnIdentity(); } /// /// 添加实体数据,并返回主键值(主键为自增long类型id,实体需要设置主键特性)(为null字段不更新,注意model有默认值的情况) /// /// /// /// (事务的db对象) /// public static long InsertModel_BigIdentity(T t, SqlSugarClient db) where T : class, new() { // Where(true/*不插入null值的列*/,false/*不插入主键值*/) return db.Insertable(t). // IgnoreColumns(p=>p.Equals("id",StringComparison.InvariantCultureIgnoreCase)). IgnoreColumns(true, false).ExecuteReturnBigIdentity(); } /// /// 添加实体数据,删除缓存,并返回主键值(主键为自增int类型id,实体需要设置主键特性)(为null字段不更新,注意model有默认值的情况) /// /// /// /// (事务的db对象) /// public static int InsertModel_RemoveDataCache(T t, SqlSugarClient db) where T : class, new() { // Where(true/*不插入null值的列*/,false/*不插入主键值*/) return db.Insertable(t). // IgnoreColumns(p=>p.Equals("id",StringComparison.InvariantCultureIgnoreCase)). IgnoreColumns(true, false).RemoveDataCache().ExecuteReturnIdentity(); } /// /// 添加实体数据,并返回主键值(主键为自增long类型id,实体需要设置主键特性)(为null字段不更新,注意model有默认值的情况) /// /// /// /// (事务的db对象) /// public static long InsertModel_BigIdentity_RemoveDataCache(T t, SqlSugarClient db) where T : class, new() { // Where(true/*不插入null值的列*/,false/*不插入主键值*/) return db.Insertable(t). // IgnoreColumns(p=>p.Equals("id",StringComparison.InvariantCultureIgnoreCase)). IgnoreColumns(true, false).RemoveDataCache().ExecuteReturnBigIdentity(); } /// /// 根据主键更新实体,返回影响条数(实体字段要有主键特性) /// /// /// /// (事务的db对象) /// public static int UpdateModelByKey(T t, SqlSugarClient db) where T : class, new() { // 字段null,不进行更新 return db.Updateable(t).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommand(); } /// /// 根据条件表达式更新实体(为null字段不更新,注意model有默认值的情况),返回影响条数 /// /// /// /// 条件表达式 /// (事务的db对象) /// public static int UpdateModelsIgnoreNull(T t, Expression> expressionWhere, SqlSugarClient db) where T : class, new() { return db.Updateable(t).IgnoreColumns(ignoreAllNullColumns: true).Where(expressionWhere).ExecuteCommand(); } /// /// 根据条件表达式更新实体(指定要更新的列),返回影响条数 /// /// /// /// /// 条件表达式 /// (事务的db对象) /// public static int UpdateModels(T t, Expression> columns, Expression> expressionWhere, SqlSugarClient db) where T : class, new() { return db.Updateable(t).UpdateColumns(columns).Where(expressionWhere).ExecuteCommand(); } /// /// 动态更新 /// /// /// 要更新的字段 /// where条件表达式 /// /// public static int Update(Expression> columns, Expression> expressionWhere, SqlSugarClient db) where T : class, new() { return db.Updateable().SetColumns(columns). // IgnoreColumns(ignoreAllNullColumns: true).// 不能加此方法,会有“CommandText 属性尚未初始化”异常 Where(expressionWhere).ExecuteCommand(); /* 调用示例 Update(p => new Entity.SysAdmin { photo = photo, Password = newPwd } ,p => p.ID == sm.id && p.Password == oldPwd ,db) > 0; */ } /// /// 根据主键更新实体,返回影响条数(实体字段要有主键特性)并删除缓存,返回影响条数(实体字段要有主键特性) /// /// /// /// (事务的db对象) /// public static int UpdateModelByKey_RemoveDataCache(T t, SqlSugarClient db) where T : class, new() { // 字段null,不进行更新 return db.Updateable(t).IgnoreColumns(ignoreAllNullColumns: true).RemoveDataCache().ExecuteCommand(); } /// /// 根据条件表达式更新实体(指定要更新的列)并删除缓存,返回影响条数 /// /// /// /// /// 条件表达式 /// (事务的db对象) /// public static int UpdateModels_RemoveDataCache(T t, Expression> columns, Expression> expressionWhere, SqlSugarClient db) where T : class, new() { return db.Updateable(t).UpdateColumns(columns).Where(expressionWhere).RemoveDataCache().ExecuteCommand(); } /// /// 动态更新,并删除缓存 /// /// /// 要更新的字段 /// where条件表达式 /// /// public static int Update_RemoveDataCache(Expression> columns, Expression> expressionWhere, SqlSugarClient db) where T : class, new() { return db.Updateable().SetColumns(columns). // IgnoreColumns(ignoreAllNullColumns: true).// 不能加此方法,会有“CommandText 属性尚未初始化”异常 Where(expressionWhere).RemoveDataCache().ExecuteCommand(); /* 调用示例 Update(p => new Entity.SysAdmin { photo = photo, Password = newPwd } ,p => p.ID == sm.id && p.Password == oldPwd ,db) > 0; */ } /// /// 删除ids集合条件的字符串(高效率写法,注意防止注入攻击) /// /// ids为字符串 "1,2,3"或"1" 形式 /// (事务的db对象) /// 主键字段 /// public static bool DeleteByWhereSql_ids(string ids, SqlSugarClient db, string key = "id") where T : class, new() { return db.Deleteable().Where(string.Format(" {0} IN ({1})", key, ids)).ExecuteCommand() > 0; } /// /// 根据条件表达式删除,返回影响条数 /// /// /// 表达式 /// (事务的db对象) /// public static int DeleteModels(Expression> expression, SqlSugarClient db) where T : class, new() { return db.Deleteable().Where(expression).ExecuteCommand(); } } }