using Microsoft.Extensions.Configuration; using Rhea.Common; using SqlSugar; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text.RegularExpressions; namespace Tiger.Business { /// /// 数据源 /// public class DataSource { /// /// 数据源 /// /// private DataSource(IConfiguration config) { var dbs = config.AsEnumerable().Where(q => q.Key.StartsWith("Databases:") && q.Value.IsNullOrEmpty()); foreach (var item in dbs) { try { Add(new Database() { Name = item.Key.Replace("Databases:", ""), Type = Enum.Parse(config[$"{item.Key}:DbType"]), ConnectionString = config[$"{item.Key}:ConnectionString"], }); } catch (System.Exception ex) { Logger.Console.Fatal(ex, $"Add Database[{item.Key.Replace("Databases:", "")}] to DataSource Exception"); } } } #region 单例 private static DataSource _DataSource = null; /// /// 创建数据源单例 /// /// /// public static DataSource CreateInstance(IConfiguration _configuration) { if (_DataSource == null) { _DataSource = new DataSource(_configuration); } return _DataSource; } #endregion /// /// 数据库列表 /// public List Databases = new List(); /// /// 按数据库名称获取数据库实例 /// /// /// public Database this[string name] => Databases.FirstOrDefault(q => q.Name == name); /// /// 按Index获取数据库实例 /// /// /// public Database this[int index] => (Databases.Count > index && index >= 0) ? Databases[index] : null; /// /// 是否存在传入名称的数据库实例 /// /// /// public bool Exists(string name) { return Databases.Any(q => q.Name == name); } /// /// 添加数据库到数据源,如果已存在相同名称的数据库则替换 /// /// /// public DataSource Add(Database database) { Databases.RemoveAll(q => q.Name == database.Name); Databases.Add(database); return this; } /// /// 按数据库名称从数据源移除数据库 /// /// /// public DataSource Remove(string name) { Databases.RemoveAll(q => q.Name == name); return this; } } /// /// 数据库 /// public class Database { /// /// 数据名称 /// public string Name { get; set; } /// /// 数据库类型 /// public DbType Type { get; set; } /// /// 连接字符串 /// public string ConnectionString { get; set; } /// /// 数据库客户端 /// public DbClient Client { get => CreateContext().Db; } /// /// 数据库基础方法 /// public DbBase Base { get => new DbBase(Client); } /// /// 创建数据库上下文 /// /// public DbContext CreateContext() { DbContext context = null; switch (Type) { case DbType.Sqlite: context = new DbContext(ConnectionString.Replace("..\\", AppDomain.CurrentDomain.BaseDirectory), DbType.Sqlite); break; default: context = new DbContext(ConnectionString, Type); break; } return context; } } /// /// 数据库上下文 /// public class DbContext { /// /// 数据库客户端 /// public DbClient Db;//用来处理事务多表查询和复杂的操作 /// /// 构造函数 /// /// 数据库连接字符串 /// 数据库类型 public DbContext(string connStr, DbType dbType) { InitDataBase(connStr, dbType); } /// /// 初始化数据库连接 /// /// 数据库连接字符串 /// 数据库类型 private void InitDataBase(string connStr, DbType dbType) { Db = new DbClient(new ConnectionConfig() { ConnectionString = connStr, DbType = dbType, IsAutoCloseConnection = true, //MoreSettings = new ConnMoreSettings() { DbMinDate = DateTime.MinValue } }); Db.Ado.CommandTimeOut = 30000;//设置超时时间 Db.Aop.OnLogExecuted = (sql, pars) => //SQL执行完事件 { //这里可以查看执行的sql语句跟参数 }; Db.Aop.OnLogExecuting = (sql, pars) => //SQL执行前事件 { //这里可以查看执行的sql语句跟参数 ConsoleExt.WriteLine //Debug.WriteLine($"****************************************** Sql Trace {DateTime.Now.ToString("HH:mm:ss")} ******************************************" + // $"\r\n{sql};{(pars.Length == 0 ? "" : "\r\n--Params:" + Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)))}\r\n"); var sqlTrace = $"------------------------------------------ Sql Trace {DateTime.Now.ToString("HH:mm:ss")} ------------------------------------------"; var sqlcmd = sql.ToUpper(); foreach (var par in pars.OrderByDescending(q => q.ParameterName.Length)) { sqlcmd = sqlcmd.Replace(par.ParameterName.ToUpper(), $"'{par.Value}'", StringComparison.CurrentCultureIgnoreCase); } sqlTrace += $"\r\n{sqlcmd.Replace("\r", "").Replace("\n", "")};\r\n-- SQL:{sql.Replace("\r", "").Replace("\n", "")}{(pars.Length == 0 ? "" : "\r\n-- Params:" + Db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)))}\r\n"; if (!sqlTrace.Contains("LOG_API_ACCESS")) { Debug.WriteLine(sqlTrace); } }; Db.Aop.OnError = (exp) =>//执行SQL 错误事件 { //这里可以查看执行的sql语句跟参数 }; Db.Aop.OnExecutingChangeSql = (sql, pars) => //SQL执行前 可以修改SQL { if (pars != null) { foreach (var par in pars) { var dbMinDate = (Db.CurrentConnectionConfig.MoreSettings?.DbMinDate ?? Convert.ToDateTime("1900-01-01")); if (par.DbType == System.Data.DbType.Int16 && (par.Value?.Equals(Int16.MinValue) ?? false)) { par.Value = null; } if (par.DbType == System.Data.DbType.Int32 && (par.Value?.Equals(Int32.MinValue) ?? false)) { par.Value = null; } if (par.DbType == System.Data.DbType.Int64 && (par.Value?.Equals(Int64.MinValue) ?? false)) { par.Value = null; } if (par.DbType == System.Data.DbType.Single && (par.Value?.Equals(Single.MinValue) ?? false)) { par.Value = null; } if (par.DbType == System.Data.DbType.Decimal && (par.Value?.Equals(Decimal.MinValue) ?? false)) { par.Value = null; } if (par.DbType == System.Data.DbType.Double && (par.Value?.Equals(Double.MinValue) ?? false)) { par.Value = null; } if (par.DbType == System.Data.DbType.Date && ((par.Value?.Equals(DateTime.MinValue) ?? false) || (par.Value?.Equals(dbMinDate) ?? false))) { par.Value = null; } if (par.DbType == System.Data.DbType.Time && ((par.Value?.Equals(DateTime.MinValue) ?? false) || (par.Value?.Equals(dbMinDate) ?? false))) { par.Value = null; } if (par.DbType == System.Data.DbType.DateTime && ((par.Value?.Equals(DateTime.MinValue) ?? false) || (par.Value?.Equals(dbMinDate) ?? false))) { par.Value = null; } if (par.DbType == System.Data.DbType.DateTime2 && ((par.Value?.Equals(DateTime.MinValue) ?? false) || (par.Value?.Equals(dbMinDate) ?? false))) { par.Value = null; } } } //适用Oracle:如果等于的值前面带N则去掉 if (sql.Contains("=N'")) { sql = sql.Replace("=N'", "='"); Debug.WriteLine("适用Oracle:如果等于的值前面带N则去掉,把存在的字符[=N']替换为[=']"); } //适用Oracle,Sqlite:如果ID字段在Update语句的Set中则删掉,不更新ID字段的值 if ((sql.StartsWith("Begin\r\nUPDATE") || sql.StartsWith("UPDATE")) && Regex.Match(sql, @"(""|`)ID(""|`)[ ]?=[ ]?('([^']*)'|:ID|@ID),", RegexOptions.Multiline).Success) { sql = Regex.Replace(sql, @"(""|`)ID(""|`)[ ]?=[ ]?('([^']*)'|:ID|@ID),", "", RegexOptions.Multiline); Debug.WriteLine("适用Oracle,Sqlite:ID字段在Update语句的Set中则删掉,不需更新ID字段的值,把存在的字符[`ID`=@ID,]替换为空[]"); } return new KeyValuePair(sql, pars); }; } } }