SqlsugarSetup.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. using Infrastructure;
  2. using Infrastructure.Model;
  3. using Microsoft.AspNetCore.Hosting;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Microsoft.Extensions.Hosting;
  6. using SqlSugar.IOC;
  7. using ZR.Common;
  8. using ZR.Model.System;
  9. namespace ZR.ServiceCore.SqlSugar
  10. {
  11. public static class SqlsugarSetup
  12. {
  13. private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
  14. /// <summary>
  15. /// 初始化db
  16. /// </summary>
  17. /// <param name="services"></param>
  18. /// <param name="environment"></param>
  19. public static void AddDb(this IServiceCollection services, IWebHostEnvironment environment)
  20. {
  21. var options = App.OptionsSetting;
  22. List<DbConfigs> dbConfigs = options.DbConfigs;
  23. var iocList = new List<IocConfig>();
  24. foreach (var item in dbConfigs)
  25. {
  26. iocList.Add(new IocConfig()
  27. {
  28. ConfigId = item.ConfigId,
  29. ConnectionString = item.Conn,
  30. DbType = (IocDbType)item.DbType,
  31. IsAutoCloseConnection = item.IsAutoCloseConnection
  32. });
  33. }
  34. SugarIocServices.AddSqlSugar(iocList);
  35. ICacheService cache;
  36. if (options.RedisServer.DbCache)
  37. {
  38. cache = new SqlSugarRedisCache();
  39. }
  40. else
  41. {
  42. cache = new SqlSugarCache();
  43. }
  44. SugarIocServices.ConfigurationSugar(db =>
  45. {
  46. var user = App.User;
  47. if (user != null)
  48. {
  49. DataPermi.FilterData("0");
  50. }
  51. iocList.ForEach(iocConfig =>
  52. {
  53. SetSugarAop(db, iocConfig, cache);
  54. });
  55. });
  56. if (environment.IsDevelopment())
  57. {
  58. InitTable.InitDb(options.InitDb);
  59. InitTable.InitNewTb();
  60. }
  61. }
  62. /// <summary>
  63. /// 数据库Aop设置
  64. /// </summary>
  65. /// <param name="db"></param>
  66. /// <param name="iocConfig"></param>
  67. /// <param name="cache"></param>
  68. private static void SetSugarAop(SqlSugarClient db, IocConfig iocConfig, ICacheService cache)
  69. {
  70. var config = db.GetConnectionScope(iocConfig.ConfigId).CurrentConnectionConfig;
  71. var showDbLog = AppSettings.Get<bool>("ShowDbLog");
  72. string configId = config.ConfigId;
  73. db.GetConnectionScope(configId).Aop.OnLogExecuting = (sql, pars) =>
  74. {
  75. if (showDbLog)
  76. {
  77. string log = $"【db{configId} SQL】{UtilMethods.GetSqlString(config.DbType, sql, pars)}\n";
  78. if (sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
  79. {
  80. logger.Info(log);
  81. }
  82. else if (sql.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase) || sql.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase))
  83. {
  84. logger.Warn(log);
  85. }
  86. else if (sql.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase) || sql.StartsWith("TRUNCATE", StringComparison.OrdinalIgnoreCase))
  87. {
  88. logger.Error(log);
  89. }
  90. else
  91. {
  92. log = $"【db{configId} SQL语句】dbo.{sql} {string.Join(", ", pars.Select(x => x.ParameterName + " = " + GetParsValue(x)))};\n";
  93. logger.Info(log);
  94. }
  95. }
  96. };
  97. db.GetConnectionScope(configId).Aop.OnError = (ex) =>
  98. {
  99. //var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
  100. string sql = $"【错误SQL,db={configId}】{UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres)}\r\n";
  101. logger.Error(ex, $"{sql}\r\n{ex.Message}\r\n{ex.StackTrace}");
  102. };
  103. db.GetConnectionScope(configId).Aop.DataExecuting = (oldValue, entiyInfo) =>
  104. {
  105. };
  106. //差异日志功能
  107. db.GetConnectionScope(configId).Aop.OnDiffLogEvent = it =>
  108. {
  109. //操作前记录 包含: 字段描述 列名 值 表名 表描述
  110. var editBeforeData = it.BeforeData;//插入Before为null,之前还没进库
  111. //操作后记录 包含: 字段描述 列名 值 表名 表描述
  112. var editAfterData = it.AfterData;
  113. var sql = it.Sql;
  114. var parameter = it.Parameters;
  115. var data = it.BusinessData;//这边会显示你传进来的对象
  116. var time = it.Time;
  117. var diffType = it.DiffType;//enum insert 、update and delete
  118. string name = App.UserName;
  119. foreach (var item in editBeforeData)
  120. {
  121. var pars = db.Utilities.SerializeObject(item.Columns.ToDictionary(it => it.ColumnName, it => it.Value));
  122. SqlDiffLog log = new()
  123. {
  124. BeforeData = pars,
  125. BusinessData = data?.ToString(),
  126. DiffType = diffType.ToString(),
  127. Sql = sql,
  128. TableName = item.TableName,
  129. UserName = name,
  130. AddTime = DateTime.Now,
  131. ConfigId = configId
  132. };
  133. if (editAfterData != null)
  134. {
  135. var afterData = editAfterData?.First(x => x.TableName == item.TableName);
  136. var afterPars = db.Utilities.SerializeObject(afterData?.Columns.ToDictionary(it => it.ColumnName, it => it.Value));
  137. log.AfterData = afterPars;
  138. }
  139. //logger.WithProperty("title", data).Info(pars);
  140. db.GetConnectionScopeWithAttr<SqlDiffLog>()
  141. .Insertable(log)
  142. .ExecuteReturnSnowflakeId();
  143. }
  144. };
  145. db.GetConnectionScope(configId).CurrentConnectionConfig.MoreSettings = new ConnMoreSettings()
  146. {
  147. IsAutoRemoveDataCache = true
  148. };
  149. db.GetConnectionScope(configId).CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices()
  150. {
  151. DataInfoCacheService = cache,
  152. EntityService = (c, p) =>
  153. {
  154. if (p.IsPrimarykey == true)//主键不能为null
  155. {
  156. p.IsNullable = false;
  157. }
  158. else if (p.ExtendedAttribute?.ToString() == ProteryConstant.NOTNULL.ToString())
  159. {
  160. p.IsNullable = false;
  161. }
  162. else//则否默认为null
  163. {
  164. p.IsNullable = true;
  165. }
  166. if (config.DbType == DbType.PostgreSQL)
  167. {
  168. if (c.Name == nameof(SysMenu.IsCache) || c.Name == nameof(SysMenu.IsFrame))
  169. {
  170. p.DataType = "char(1)";
  171. }
  172. }
  173. #region 兼容sqllite
  174. if (config.DbType == DbType.Sqlite)
  175. {
  176. if (p.IsPrimarykey && c.PropertyType == typeof(long))
  177. {
  178. p.DataType = "INTEGER";
  179. }
  180. }
  181. #endregion
  182. #region 兼容Oracle
  183. if (config.DbType == DbType.Oracle)
  184. {
  185. if (p.IsIdentity == true)
  186. {
  187. if (p.EntityName == nameof(SysUser))
  188. {
  189. p.OracleSequenceName = "SEQ_SYS_USER_USERID";
  190. }
  191. else if (p.EntityName == nameof(SysRole))
  192. {
  193. p.OracleSequenceName = "SEQ_SYS_ROLE_ROLEID";
  194. }
  195. else if (p.EntityName == nameof(SysDept))
  196. {
  197. p.OracleSequenceName = "SEQ_SYS_DEPT_DEPTID";
  198. }
  199. else if (p.EntityName == nameof(SysMenu))
  200. {
  201. p.OracleSequenceName = "SEQ_SYS_MENU_MENUID";
  202. }
  203. else
  204. {
  205. p.OracleSequenceName = "SEQ_ID";
  206. }
  207. }
  208. }
  209. #endregion
  210. }
  211. };
  212. db.GetConnectionScope(configId).Aop.OnLogExecuted = (sql, pars) =>
  213. {
  214. var sqlExecutionTime = AppSettings.Get<int>("sqlExecutionTime");
  215. if (db.Ado.SqlExecutionTime.TotalSeconds > sqlExecutionTime)
  216. {
  217. //代码CS文件名
  218. var fileName = db.Ado.SqlStackTrace.FirstFileName;
  219. //代码行数
  220. var fileLine = db.Ado.SqlStackTrace.FirstLine;
  221. //方法名
  222. var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName;
  223. var logInfo = $"Sql执行超时,用时{db.Ado.SqlExecutionTime.TotalSeconds}秒【{sql}】,fileName={fileName},line={fileLine},methodName={FirstMethodName}";
  224. WxNoticeHelper.SendMsg("Sql请求时间过长", logInfo);
  225. logger.Warn(logInfo);
  226. }
  227. };
  228. }
  229. private static object GetParsValue(SugarParameter x)
  230. {
  231. if (x.DbType == System.Data.DbType.String || x.DbType == System.Data.DbType.DateTime || x.DbType == System.Data.DbType.String)
  232. {
  233. return "'" + x.Value + "'";
  234. }
  235. return x.Value;
  236. }
  237. }
  238. }