using SqlSugar; using System.Text.Json; using WinFormsApp.Utils; namespace guoke { /// /// 数据库服务 /// public class DatabaseService { LogService log; /// /// 数据库配置字典 /// static Dictionary dbConf=new Dictionary(); public DatabaseService(LogService logService) { //StaticConfig.DynamicExpressionParserType = typeof(DynamicExpressionParser); log = logService; List configs = ConfigReader.GetObject>("DB"); foreach (DatabaseConfig config in configs) { dbConf.Add(config.Name, config); } } /// /// 单例模式对象字段 /// static Dictionary SugarScope = new Dictionary(); /// /// 获取单例模式对象 可以跨线程 /// /// /// public SqlSugarScope GetScope(string dbName) { if (dbConf.TryGetValue(dbName, out var conf)) { if (SugarScope.ContainsKey(dbName))//单例模式以创建 { return SugarScope[dbName]; } else //创建在返回 { SqlSugarScope db = new SqlSugarScope(new ConnectionConfig() { ConfigId = conf.Name, ConnectionString = conf.Connection, DbType = conf.Type, IsAutoCloseConnection = true, }, db => { db.Aop.OnLogExecuting = (sql, pars) => { if (conf.Print) { var currentDbName = db.CurrentConnectionConfig.ConfigId; log.Debug($"数据库{currentDbName}", $"sql:{sql}"); } }; }); db.Ado.CommandTimeOut = 1;//单位秒 SugarScope.Add(dbName, db);//添加到单例字典 return db; } } else log.Warn("数据库", $"没有{dbName}对应的数据库"); return null; } /// /// 获取仓库对象 单例模式 可以跨线程 /// /// /// /// /// public WarehouseScope GetWarehouseScope(string dbName, bool checkTable = false) where T : class, IBaseTableModel, new() { return new WarehouseScope(log, GetScope(dbName), checkTable); } /// /// 获取客户端对象 不可以跨线程 /// /// 数据库名称 /// public SqlSugarClient GetClient(string dbName) { if (dbConf.TryGetValue(dbName, out var conf)) { SqlSugarClient db= new SqlSugarClient(new ConnectionConfig() { ConfigId = conf.Name, ConnectionString = conf.Connection, DbType = conf.Type, IsAutoCloseConnection = true, }, db => { db.Aop.OnLogExecuting = (sql, pars) => { if (conf.Print) { var currentDbName = db.CurrentConnectionConfig.ConfigId; log.Debug($"数据库{currentDbName}", $"sql:{sql}"); } }; }); db.Ado.CommandTimeOut = 1;//单位秒 return db; } else log.Warn("数据库", $"没有{dbName}对应的数据库"); return null; } /// /// 获取仓库客户端对象 不可以跨线程 /// /// /// /// /// public WarehouseClient GetWarehouseClient(string dbName, bool checkTable = false) where T : class, IBaseTableModel, new() { return new WarehouseClient(log, GetClient(dbName)); } /// /// 获取仓库 /// /// 模型类型 /// 数据库连接对象 /// public Repository GetWarehouse(ISqlSugarClient db, bool checkTable = false) where T : class, IBaseTableModel, new() { return new Repository(db, checkTable); } /// /// 获取仓库 /// /// 模型类型 /// 数据库名称 /// public Repository GetWarehouse(string dbName, bool checkTable = false) where T : class, IBaseTableModel, new() { ISqlSugarClient db = GetClient(dbName); return new Repository(db, checkTable); } /// /// 只是方法名称不一样 主要为了用在反射中唯一性 /// /// /// /// /// public Repository GetWarehouseRef(string dbName, bool checkTable = false) where T : class, IBaseTableModel, new() { ISqlSugarClient db = GetClient(dbName); return new Repository(db, checkTable); } /// /// 获取数据库配置 /// /// /// public DatabaseConfig GetConfig(string name) { if (dbConf.TryGetValue(name, out var conf)) { return conf; } else log.Warn("数据库", $"没有{name}对应的数据库配置"); return null; } /// /// 根据类型获取表名 /// /// 模型类型 /// public string GetTableName(Type type) { object[] attributes = type.GetCustomAttributes(typeof(SugarTable), false); if (attributes.Length > 0) { SugarTable sugarTable = (SugarTable)attributes[0]; return sugarTable.TableName; } return type.Name; } } /// public class WarehouseBase where T : class, IBaseTableModel, new() { //var db = Mode ? (dynamic)Scope : Client; /// /// 获取雪花ID /// public long NextId { get { return SnowFlakeSingle.Instance.NextId(); } } /// /// 模式 true=单例模式 false=客户端模式 /// protected bool Mode { get; set; } /// /// 日志服务 /// public LogService log { get; set; } /// /// 单例模式实例 /// protected SqlSugarScope Scope { get; set; } /// /// 客户端实例 /// protected SqlSugarClient Client { get; set; } /// /// 仓储表名 /// public string TableName { get; set; } /// /// 连接状态 /// public bool ConnStatus{ get { var db = Mode ? (dynamic)Scope : Client; return db.Ado.IsValidConnection(); }} /// /// 数据库安全性检查 /// /// public bool DatabaseSecurityCheck() { var db = Mode ? (dynamic)Scope : Client; if (db == null) { LogService.Log.Warn("数据库", "数据库连接对象空"); return true; } if (!db.Ado.IsValidConnection()) { LogService.Log.Warn("数据库", "数据库连接断开"); return true; } return false; } #region 表相关 /// /// 检查表 /// /// public bool CheckTable() { string tableName = GetTableName(typeof(T));// typeof(T).Name; if (Mode) { return Scope.DbMaintenance.IsAnyTable(tableName);//判断状态表是否存在 } else { return Client.DbMaintenance.IsAnyTable(tableName);//判断状态表是否存在 } } /// /// 检查表 /// /// public bool CheckTable(string tableName) { if (Mode) { return Scope.DbMaintenance.IsAnyTable(tableName);//判断状态表是否存在 } else { return Client.DbMaintenance.IsAnyTable(tableName);//判断状态表是否存在 } } /// /// 检查并创建 /// /// public bool CheckToCreate() { try { string tableName = GetTableName(typeof(T));//获取表名 if (!CheckTable(tableName)) { if (Mode) { if (Scope.MappingTables == null) { Scope.MappingTables = new MappingTableList(); } Scope.MappingTables.Add(typeof(T).Name, tableName); // 类名 表名 Scope.CodeFirst.InitTables(typeof(T)); //创建表 } else { if (Client.MappingTables == null) { Client.MappingTables = new MappingTableList(); } Client.MappingTables.Add(typeof(T).Name, tableName); // 类名 表名 Client.CodeFirst.InitTables(typeof(T)); //创建表 } log.Info("仓库", $"创建表:{tableName},模型:{typeof(T).Name}"); } return true; } catch (Exception e) { log.Error("数据库", $"检查创建表错误:{e.Message}"); return false; } } /// /// 根据类型获取表名 /// /// 模型类型 /// public string GetTableName(Type type) { object[] attributes = type.GetCustomAttributes(typeof(SugarTable), false); if (attributes.Length > 0) { SugarTable sugarTable = (SugarTable)attributes[0]; return sugarTable.TableName; } return type.Name; } #endregion } /// /// 仓储单例模式 可以跨线程 /// /// public class WarehouseScope: WarehouseBase where T : class, IBaseTableModel, new() { /// /// 数据库对象 /// public SqlSugarScope Db{ get;} /// /// 构建仓储 /// /// /// /// public WarehouseScope (LogService logService, SqlSugarScope db, bool checkTable = false) { base.Mode = true; base.Scope = db; base.log = logService; this.Db= db; this.TableName = GetTableName(typeof(T));//获取表名 if (checkTable) { CheckToCreate(); } } } /// /// 仓储客户端模式 不能跨线程 /// /// public class WarehouseClient: WarehouseBase where T : class, IBaseTableModel, new() { /// /// 数据库对象 /// public SqlSugarClient Db { get; } /// /// 构建仓储 /// /// /// /// public WarehouseClient(LogService logService, SqlSugarClient db, bool checkTable = false) { base.Mode = false; base.Client = db; base.log = logService; this.Db = db; this.TableName = GetTableName(typeof(T));//获取表名 if (checkTable) { CheckToCreate(); } } } /// /// 创建仓库 /// /// public class Repository : SimpleClient where T : class, IBaseTableModel,new() { /// /// 获取雪花ID /// public long NextId { get { return SnowFlakeSingle.Instance.NextId(); } } /// /// /// private ISqlSugarClient db; /// /// 数据库连接对象 /// public ISqlSugarClient Db { get => db;} /// /// 空表名 /// private string tableName = "空表名"; /// /// 日志 /// LogService log; /// /// 创建仓库 /// /// 数据库连接实例 /// 是否创建表 public Repository(ISqlSugarClient dbClient,bool checkTable=false) { log = LogService.Log; base.Context = dbClient;//赋值给基类 db = dbClient; tableName = GetTableName(typeof(T));//获取表名 if (db.Ado.IsValidConnection()) { if (checkTable) { CheckToCreate(); } } else { log.Error("仓储", $"{typeof(T).Name}数据库连接不成功"); } } /// /// 数据库连接状态 /// /// public bool Connection() { return db.Ado.IsValidConnection(); } #region 工具方法 /// /// 从json字符串中对象中获取所有属性的key /// /// key的数据 /// public List GetKeysFromJson(string jsonString) { // 将 JSON 字符串解析为字典 var dictionary = JsonSerializer.Deserialize>(jsonString); // 获取所有的键并转换为列表 List keys = new List(dictionary.Keys); return keys; } #endregion #region 表相关 /// /// 检查表 /// /// public bool CheckTable(string tableName) { return Db.DbMaintenance.IsAnyTable(tableName);//判断状态表是否存在 } /// /// 检查表 /// /// public bool CheckTable() { string tableName = GetTableName(typeof(T));// typeof(T).Name; return Db.DbMaintenance.IsAnyTable(tableName);//判断状态表是否存在 } /// /// 检查并创建 /// /// public bool CheckToCreate() { try { string tableName = GetTableName(typeof(T));//获取表名 if (!Db.DbMaintenance.IsAnyTable(tableName))//判断状态表是否存在 { if (Db.MappingTables == null) { Db.MappingTables = new MappingTableList(); } Db.MappingTables.Add(typeof(T).Name, tableName); // 类名 表名 Db.CodeFirst.InitTables(typeof(T)); //创建表 log.Info("仓库", $"创建表:{tableName},模型:{typeof(T).Name}"); } return true; } catch (Exception e) { return false; } } /// /// 根据类型获取表名 /// /// 模型类型 /// string GetTableName(Type type) { object[] attributes = type.GetCustomAttributes(typeof(SugarTable), false); if (attributes.Length > 0) { SugarTable sugarTable = (SugarTable)attributes[0]; return sugarTable.TableName; } return type.Name; } #endregion #region 增 /// /// 增加数据 /// /// /// public int Insert( List data) { return Db.Insertable(data).ExecuteCommand(); } #endregion #region 插入更新 /// /// 存在数据库更新 不存在插入 (默认是主键) /// /// /// public int InsertUpdate(T data) { return db.Storageable(data).ExecuteCommand(); } #endregion #region 删 /// /// 删除指定时间之前的数据 /// /// /// /// public int DeleteDataByHours(int hours) { DateTime targetTime = DateTime.Now.AddHours(-hours);// 计算要删除数据的时间点 return db.Deleteable().Where(it => it.CreateTime < targetTime).ExecuteCommand(); } /// /// 删除当前时间指定天数之前的数据 /// /// /// public int DeleteDataByDay(int day) { DateTime targetTime = DateTime.Now.AddDays(-day);// 计算要删除数据的时间点 return db.Deleteable().Where(it => it.CreateTime < targetTime).ExecuteCommand(); } /// /// 已创建时间保留最新N条数据 其余删除 /// /// /// public int ClearTheLatestNItems(int N) { return db.Deleteable().In(it => it.Id,db.Queryable().Skip(10).OrderByDescending(it => it.CreateTime)//Take(10)最新10条2个有区别 .Select(it => it.Id)).ExecuteCommand(); } #endregion #region 改 /// /// 设置同步状态 /// /// /// public int SetSyncStatus(T data) { data.SyncStatus = 1; return db.Updateable(data).UpdateColumns(it => new { it.SyncStatus}).ExecuteCommand(); } #endregion #region 查 /// /// 查询记录是否存在 /// /// 字段名称 /// 字段值 /// 条件类型 默认==等于 /// public bool Queryable(string fieldName,object fieldValue, string conditionalType="==") { return db.Queryable().Where( fieldName, conditionalType, fieldValue).Any(); } /// /// 分页查询 /// /// /// /// /// /// /// public List QueryPage(int pageNumber, int pageSize, ref int totalNumber, ref int totalPage) { return db.Queryable().ToPageList(pageNumber, pageSize, ref totalNumber, ref totalPage); } /// /// 获取未同步的数据10条 /// /// public List GetUnsynchronizedData() { return db.Queryable().Take(10).Where(it=>it.SyncStatus==0).ToList(); } #endregion } /// /// 数据库配置模型 /// public class DatabaseConfig { // 数据库名称 public string Name { get; set; } // 数据库是否使能 public bool Enabled { get; set; }=false; // 数据库类型,例如 "SQLServer", "MySQL", "PostgreSQL" 等 public DbType Type { get; set; } = DbType.Sqlite; // 数据库连接字符串 public string Connection { get; set; } // 数据库配置备注 public string Remarks { get; set; } = ""; // 是否打印日志等相关信息 public bool Print { get; set; } = false; } /// /// 数据库基类接口 /// public interface IBaseTableModel { int Id { get; set; } DateTime CreateTime { get; set; } DateTime UpdateTime { get; set; } string Remarks { get; set; } int SyncStatus { get; set; } } /// /// 数据模型基类 /// public class BaseTableModel: IBaseTableModel { // 主键 ID [SugarColumn(IsIdentity = true, IsPrimaryKey = true, ColumnDescription = "主键")]//主键标识 自增标识 public int Id { get; set; } // 创建时间 [SugarColumn(ColumnDescription = "创建时间")] public DateTime CreateTime { get; set; }= DateTime.Now; // 更新时间 [SugarColumn(ColumnDescription = "更新时间")] public DateTime UpdateTime { get; set; } = DateTime.Now; // 同步状态 [SugarColumn(ColumnDescription = "同步状态")] public int SyncStatus { get; set; } = 0; // 备注信息 [SugarColumn(ColumnDescription = "备注信息", IsNullable = true)] public string Remarks { get; set; } = ""; } /// /// 数据库同步特性 /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public class DatabaseSyncAttribute : Attribute { /// /// 源数据库 /// public string Source { get; } /// /// 目标数据库 /// public string Target { get; } /// /// 清理使能 /// public bool CleanupEnabled { get; set; } = false; // 默认不清理 /// /// 清理模式 false 默认保留天数 /// public bool CleanupMode { get; set; } = false; /// /// 保留数 CleanupMode=true (保留条数) =false (保留天数) 默认保留30天 /// public int RetentionCount { get; set; } = 30; /// /// 数据库同步特性 /// /// 源数据库 /// 目标数据库 /// 源表清理使能 /// 清理模式 =true保留条数 =false 默认保留天数 /// 保留数 CleanupMode=true (保留条数) =false (保留天数) 默认保留30天 public DatabaseSyncAttribute(string source, string target,bool cleanupEnabled=false,bool cleanupMode=false,int retentionCount=30) { Source = source; Target = target; CleanupEnabled = cleanupEnabled; CleanupMode = cleanupMode; RetentionCount = retentionCount; } } /// /// SqlSugar条件构建器,用于简化条件查询的构建 /// public class ConditionBuilder { private List _conditions = new List(); private Dictionary _namedGroups = new Dictionary(); /// /// 获取构建的条件列表 /// public List Build() { var result = new List(_conditions); // 添加所有命名条件组 foreach (var group in _namedGroups.Values) { result.Add(group.Build()); } return result; } /// /// 添加简单条件 /// /// 字段名 /// 条件类型 /// 字段值 /// 当前构建器实例 public ConditionBuilder Where(string fieldName, CondType conditionalType, object fieldValue, string cSharpTypeName=null) { _conditions.Add(new ConditionalModel { FieldName = fieldName, ConditionalType =(ConditionalType)conditionalType, FieldValue = fieldValue?.ToString(), CSharpTypeName = cSharpTypeName }); return this; } /// /// 添加等于条件 /// public ConditionBuilder WhereEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.Equal, fieldValue, cSharpTypeName); } /// /// 添加不等于条件 /// public ConditionBuilder WhereNotEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.NoEqual, fieldValue); } /// /// 添加大于条件 /// public ConditionBuilder WhereGreaterThan(string fieldName, object fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.GreaterThan, fieldValue); } /// /// 添加大于等于条件 /// public ConditionBuilder WhereGreaterThanOrEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.GreaterThanOrEqual, fieldValue, cSharpTypeName); } /// /// 添加小于条件 /// public ConditionBuilder WhereLessThan(string fieldName, object fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.LessThan, fieldValue, cSharpTypeName); } /// /// 添加小于等于条件 /// public ConditionBuilder WhereLessThanOrEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.LessThanOrEqual, fieldValue, cSharpTypeName); } /// /// 添加Like条件 /// public ConditionBuilder WhereLike(string fieldName, string fieldValue, string cSharpTypeName = null) { return Where(fieldName, CondType.Like, fieldValue, cSharpTypeName); } /// /// 添加In条件 /// public ConditionBuilder WhereIn(string fieldName, params object[] values) { return Where(fieldName, CondType.In, string.Join(",", values)); } /// /// 添加复杂条件组 /// /// 条件组构建器委托 /// 当前构建器实例 public ConditionBuilder WhereGroup(Action builderAction) { var groupBuilder = new GroupConditionBuilder(); builderAction(groupBuilder); _conditions.Add(groupBuilder.Build()); return this; } /// /// 添加命名的复杂条件组,可以在后续代码中继续添加条件 /// /// 条件组名称 /// 条件组构建器委托 /// 当前构建器实例 public ConditionBuilder WhereGroup(string groupName, Action builderAction) { if (!_namedGroups.TryGetValue(groupName, out var groupBuilder)) { groupBuilder = new GroupConditionBuilder(); _namedGroups.Add(groupName, groupBuilder); } builderAction(groupBuilder); return this; } /// /// 获取已命名的条件组构建器 /// /// 条件组名称 /// 条件组构建器 public GroupConditionBuilder GetGroup(string groupName) { if (!_namedGroups.TryGetValue(groupName, out var groupBuilder)) { groupBuilder = new GroupConditionBuilder(); _namedGroups.Add(groupName, groupBuilder); } return groupBuilder; } } /// /// 条件组构建器,用于构建复杂的条件组 /// public class GroupConditionBuilder { private List> _conditionalList = new List>(); private WhereType _defaultWhereType = WhereType.And; /// /// 设置默认的连接类型(And/Or) /// public GroupConditionBuilder SetDefaultWhereType(WhereType whereType) { _defaultWhereType = whereType; return this; } /// /// 构建条件集合 /// public ConditionalCollections Build() { return new ConditionalCollections { ConditionalList = _conditionalList }; } /// /// 添加条件(使用默认连接类型) /// public GroupConditionBuilder Where(string fieldName, CondType conditionalType, object fieldValue, string cSharpTypeName = null) { return Where(_defaultWhereType, fieldName,conditionalType, fieldValue, cSharpTypeName); } /// /// 添加条件(指定连接类型) /// public GroupConditionBuilder Where(WhereType whereType, string fieldName, CondType conditionalType, object fieldValue, string cSharpTypeName = null) { _conditionalList.Add(new KeyValuePair( whereType, new ConditionalModel { FieldName = fieldName, ConditionalType = (ConditionalType)conditionalType, FieldValue = fieldValue?.ToString(), CSharpTypeName = cSharpTypeName } )); return this; } /// /// 添加And连接的条件 /// public GroupConditionBuilder And(string fieldName, CondType conditionalType, object fieldValue, string cSharpTypeName = null) { return Where(WhereType.And, fieldName, conditionalType, fieldValue, cSharpTypeName); } /// /// 添加Or连接的条件 /// public GroupConditionBuilder Or(string fieldName, CondType conditionalType, object fieldValue, string cSharpTypeName = null) { return Where(WhereType.Or, fieldName, conditionalType, fieldValue, cSharpTypeName); } /// /// 添加And连接的等于条件 /// public GroupConditionBuilder AndEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return And(fieldName, CondType.Equal, fieldValue, cSharpTypeName); } /// /// 添加Or连接的等于条件 /// public GroupConditionBuilder OrEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return Or(fieldName, CondType.Equal, fieldValue, cSharpTypeName); } /// /// 添加And连接的不等于条件 /// public GroupConditionBuilder AndNotEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return And(fieldName, CondType.NoEqual, fieldValue, cSharpTypeName); } /// /// 添加Or连接的不等于条件 /// public GroupConditionBuilder OrNotEqual(string fieldName, object fieldValue, string cSharpTypeName = null) { return Or(fieldName, CondType.NoEqual, fieldValue, cSharpTypeName); } /// /// 添加And连接的Like条件 /// public GroupConditionBuilder AndLike(string fieldName, string fieldValue, string cSharpTypeName = null) { return And(fieldName, CondType.Like, fieldValue, cSharpTypeName); } /// /// 添加Or连接的Like条件 /// public GroupConditionBuilder OrLike(string fieldName, string fieldValue, string cSharpTypeName = null) { return Or(fieldName, CondType.Like, fieldValue, cSharpTypeName); } // 可以根据需要添加更多便捷方法 } /// /// 条件类型枚举 /// public enum CondType { /// /// 等于条件,用于判断字段值是否等于指定值 /// Equal, /// /// 模糊匹配,相当于 SQL 中的 LIKE '%value%' /// Like, /// /// 大于条件,相当于 SQL 中的 > /// GreaterThan, /// /// 大于等于条件,相当于 SQL 中的 >= /// GreaterThanOrEqual, /// /// 小于条件,相当于 SQL 中的 < /// LessThan, /// /// 小于等于条件,相当于 SQL 中的 <= /// LessThanOrEqual, /// /// 包含条件,相当于 SQL 中的 IN /// In, /// /// 不包含条件,相当于 SQL 中的 NOT IN /// NotIn, /// /// 左模糊匹配,相当于 SQL 中的 LIKE '%value' /// LikeLeft, /// /// 右模糊匹配,相当于 SQL 中的 LIKE 'value%' /// LikeRight, /// /// 不等于条件,相当于 SQL 中的 != 或 <> /// NoEqual, /// /// 判断字段是否为 null 或空 /// IsNullOrEmpty, /// /// 不是条件,用于否定判断 /// IsNot, /// /// 不包含,相当于 SQL 中的 NOT LIKE /// NoLike, /// /// 等于 null 条件 /// EqualNull, /// /// 包含模糊匹配,可以进行多个值的模糊查询 /// InLike, /// /// 范围查询,用于指定一个值的范围 /// Range } }