using BZPT.Domains.Application; using BZPT.Domains.Entity.Sys; using Castle.Core.Logging; using Microsoft.Extensions.Logging; using Mysqlx.Expr; using Newtonsoft.Json; using NPlatform.Filters; using NPlatform.Infrastructure.IdGenerators; using NPOI.HPSF; using NPOI.SS.Formula.Functions; using Serilog.Context; using Serilog.Events; using SqlSugar; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Configuration; using System.Data.SqlTypes; using System.Runtime.CompilerServices; namespace BZPT.Repositories { public partial class DBContext : SqlSugarClient { private readonly string _connectionString; private readonly DbType _dbProvider; private readonly int _timeOut; public DBContext(string connectString, DbType dbProvider, string ConfigId = "default", int timeOut = 180) : base(new ConnectionConfig() { DbType = dbProvider, ConnectionString = connectString, IsAutoCloseConnection = true, ConfigId = ConfigId, ConfigureExternalServices = new ConfigureExternalServices() { EntityService = (property, column) => { var attributes = property.GetCustomAttributes(true); if (attributes.Any(it => it is KeyAttribute)) { column.IsPrimarykey = true; } if (attributes.Any(it => it is NotMappedAttribute)) { column.IsIgnore = true; } if (attributes.Any(t => t is ColumnAttribute)) { var attr = attributes.First(it => it is ColumnAttribute) as ColumnAttribute; if(!string.IsNullOrEmpty(attr?.Name)) column.DbColumnName = attr?.Name; } }, EntityNameService = (type, entity) => { var attributes = type.GetCustomAttributes(true); if (attributes.Any(it => it is TableAttribute)) { var attr = attributes.First(it => it is TableAttribute) as TableAttribute; if(!string.IsNullOrEmpty(attr?.Name)) entity.DbTableName = attr?.Name; } } } }, dbAction) { _connectionString = connectString; _dbProvider = dbProvider; _timeOut = timeOut; } public static Action dbAction = db => { // SQL执行完 db.Aop.OnLogExecuted = (sql, pars) => { try { var strSql = UtilMethods.GetNativeSql(sql, pars); //Serilog.Log.Logger.Information($"time:{db.Ado.SqlExecutionTime.ToString()},sql:{strSql}"); } catch (Exception ex) { // 处理异常,例如记录错误日志 Serilog.Log.Logger.Error(ex, "sql执行错误"); MessageApplication.SendErrorMessage("sql执行错误:" + ex?.ToString()); } }; db.Aop.OnLogExecuting = (sql, pars) => { // 获取原生SQL推荐 5.1.4.63 性能OK // UtilMethods.GetNativeSql(sql, pars) // 获取无参数化SQL 影响性能只适合调试 // UtilMethods.GetSqlString(DbType.SqlServer, sql, pars) }; db.Aop.OnError = (exp) => { try { var sql = exp.Sql; MessageApplication.SendErrorMessage("sql执行错误:" + exp.ToString()); if (exp.Parametres != null) { foreach (var p in (exp.Parametres as SugarParameter[])) { switch (p.DbType) { case System.Data.DbType.String: case System.Data.DbType.Date: case System.Data.DbType.DateTime: sql = sql.Replace(p.ParameterName, $"'{p.Value}'"); break; default: sql = sql.Replace(p.ParameterName, $"{p.Value}"); break; } } } Serilog.Log.Logger.Error($"time:{exp?.ToString()}{db.Ado.SqlExecutionTime.ToString()},sql:{sql}"); } catch (Exception ex) { // 处理异常,例如记录错误日志 Serilog.Log.Logger.Error($"time:{exp?.Message}"); } }; db.Aop.OnExecutingChangeSql = (sql, pars) => { #if DEBUG try { var strSql = UtilMethods.GetNativeSql(sql, pars); Serilog.Log.Logger.Debug($"time:{db.Ado.SqlExecutionTime.ToString()},sql:{strSql}"); } catch (Exception ex) { Serilog.Log.Logger.Error($"OnExecutingChangeSql:{ex.ToString()}"); // 处理异常,例如记录错误日志 } #endif 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; // enum insert 、update and delete Serilog.Log.Logger.Information($"diffType:{diffType},editBeforeData:{editBeforeData},editAfterData:{editAfterData},sql:{sql},params:{JsonConvert.SerializeObject(parameter)}"); // Write logic }; db.Aop.OnLogExecuted = (sql, p) => { // 执行时间超过1秒 if (db.Ado.SqlExecutionTime.TotalSeconds > 2) { // 代码CS文件名 var fileName = db.Ado.SqlStackTrace.FirstFileName; // 代码行数 var fileLine = db.Ado.SqlStackTrace.FirstLine; // 方法名 var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName; // db.Ado.SqlStackTrace.MyStackTraceList[1].xxx 获取上层方法的信息 LogContext.PushProperty("CostTime", db.Ado.SqlExecutionTime.TotalSeconds); Serilog.Log.Logger.Warning($"SqlExecutionTime:{sql},params:{JsonConvert.SerializeObject(p)},fileName:{fileName},fileLine:{fileLine},MethodName:{FirstMethodName}"); } // 相当于EF的 PrintToMiniProfiler }; //db.Aop.DataExecuting = (oldValue, entityInfo) => //{ // /*** 列级别事件 :更新的每一列都会进事件 ***/ // if (entityInfo.PropertyName == "UpdateTime" && entityInfo.OperationType == DataFilterType.UpdateByObject) // { // entityInfo.SetValue(DateTime.Now); // 修改UpdateTime字段 // /*当前列获取特性*/ // // 5.1.3.23 + // // entityInfo.IsAnyAttribute<特性>() // // entityInfo.GetAttribute<特性>() // } // /*** 行级别事件 :更新一条记录只进一次 ***/ // if (entityInfo.EntityColumnInfo.IsPrimarykey) // { // // entityInfo.EntityValue 拿到单条实体对象 // } // /*** 根据当前列修改另一列 ***/ // // if(当前列逻辑==XXX) // // var properyDate = entityInfo.EntityValue.GetType().GetProperty("Date"); // // if(properyDate!=null) // // properyDate.SetValue(entityInfo.EntityValue,1); // // 可以写多个IF // /*** 删除生效 (只有行级事件) ***/ // if (entityInfo.OperationType == DataFilterType.DeleteByObject) // { // // entityInfo.EntityValue 拿到所有实体对象 // } //}; }; } }