DBServiceCollectionExtensions.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. using Microsoft.Extensions.DependencyInjection;
  2. using Microsoft.Extensions.Hosting;
  3. using System;
  4. using StackExchange.Profiling;
  5. using FreeSql;
  6. using FreeSql.Internal.CommonProvider;
  7. using ZhonTai.Common.Helpers;
  8. using ZhonTai.Admin.Core.Configs;
  9. using ZhonTai.Admin.Core.Entities;
  10. using ZhonTai.Admin.Core.Auth;
  11. using ZhonTai.Admin.Core.Startup;
  12. using ZhonTai.Admin.Core.Consts;
  13. using System.Linq;
  14. using System.Collections.Concurrent;
  15. using System.Reflection;
  16. namespace ZhonTai.Admin.Core.Db;
  17. public static class DBServiceCollectionExtensions
  18. {
  19. /// <summary>
  20. /// 添加主数据库
  21. /// </summary>
  22. /// <param name="services"></param>
  23. /// <param name="freeSqlCloud"></param>
  24. /// <param name="env"></param>
  25. /// <param name="hostAppOptions"></param>
  26. /// <returns></returns>
  27. public static void AddAdminDb(this IServiceCollection services, FreeSqlCloud freeSqlCloud, IHostEnvironment env, HostAppOptions hostAppOptions)
  28. {
  29. var dbConfig = ConfigHelper.Get<DbConfig>("dbconfig", env.EnvironmentName);
  30. var appConfig = ConfigHelper.Get<AppConfig>("appconfig", env.EnvironmentName);
  31. //注册主库
  32. freeSqlCloud.Register(DbKeys.MasterDb, () =>
  33. {
  34. //创建数据库
  35. if (dbConfig.CreateDb)
  36. {
  37. DbHelper.CreateDatabaseAsync(dbConfig).Wait();
  38. }
  39. var providerType = dbConfig.ProviderType.NotNull() ? Type.GetType(dbConfig.ProviderType) : null;
  40. var freeSqlBuilder = new FreeSqlBuilder()
  41. .UseConnectionString(dbConfig.Type, dbConfig.ConnectionString, providerType)
  42. .UseAutoSyncStructure(false)
  43. .UseLazyLoading(false)
  44. .UseNoneCommandParameter(true);
  45. if (dbConfig.SlaveList?.Length > 0)
  46. {
  47. var slaveList = dbConfig.SlaveList.Select(a => a.ConnectionString).ToArray();
  48. var slaveWeightList = dbConfig.SlaveList.Select(a => a.Weight).ToArray();
  49. freeSqlBuilder.UseSlave(slaveList).UseSlaveWeight(slaveWeightList);
  50. }
  51. hostAppOptions?.ConfigureFreeSqlBuilder?.Invoke(freeSqlBuilder);
  52. #region 监听所有命令
  53. if (dbConfig.MonitorCommand)
  54. {
  55. freeSqlBuilder.UseMonitorCommand(cmd => { }, (cmd, traceLog) =>
  56. {
  57. //Console.WriteLine($"{cmd.CommandText}\n{traceLog}\r\n");
  58. Console.WriteLine($"{cmd.CommandText}\r\n");
  59. });
  60. }
  61. #endregion 监听所有命令
  62. var fsql = freeSqlBuilder.Build();
  63. var user = services.BuildServiceProvider().GetService<IUser>();
  64. //软删除过滤器
  65. fsql.GlobalFilter.Apply<ISoftDelete>(FilterNames.SoftDelete, a => a.IsDeleted == false);
  66. //配置实体
  67. DbHelper.ConfigEntity(fsql, appConfig);
  68. hostAppOptions?.ConfigureFreeSql?.Invoke(fsql);
  69. #region 初始化数据库
  70. //同步结构
  71. if (dbConfig.SyncStructure)
  72. {
  73. DbHelper.SyncStructure(fsql, dbConfig: dbConfig, appConfig: appConfig);
  74. }
  75. #region 审计数据
  76. //计算服务器时间
  77. var selectProvider = fsql.Select<object>() as Select0Provider;
  78. var serverTime = fsql.Select<object>().WithSql($"select {selectProvider._commonUtils.NowUtc} a").First(a => Convert.ToDateTime("a"));
  79. var timeOffset = DateTime.UtcNow.Subtract(serverTime);
  80. DbHelper.TimeOffset = timeOffset;
  81. fsql.Aop.AuditValue += (s, e) =>
  82. {
  83. DbHelper.AuditValue(e, timeOffset, user);
  84. };
  85. #endregion 审计数据
  86. //同步数据
  87. if (dbConfig.SyncData)
  88. {
  89. DbHelper.SyncDataAsync(fsql, dbConfig, appConfig).Wait();
  90. }
  91. #endregion 初始化数据库
  92. //生成数据
  93. if (dbConfig.GenerateData && !dbConfig.CreateDb && !dbConfig.SyncData)
  94. {
  95. DbHelper.GenerateDataAsync(fsql, appConfig).Wait();
  96. }
  97. #region 监听Curd操作
  98. if (dbConfig.Curd)
  99. {
  100. fsql.Aop.CurdBefore += (s, e) =>
  101. {
  102. if (appConfig.MiniProfiler)
  103. {
  104. MiniProfiler.Current.CustomTiming("CurdBefore", e.Sql);
  105. }
  106. Console.WriteLine($"{e.Sql}\r\n");
  107. };
  108. fsql.Aop.CurdAfter += (s, e) =>
  109. {
  110. if (appConfig.MiniProfiler)
  111. {
  112. MiniProfiler.Current.CustomTiming("CurdAfter", $"{e.ElapsedMilliseconds}");
  113. }
  114. };
  115. }
  116. #endregion 监听Curd操作
  117. //租户过滤器
  118. if (appConfig.Tenant)
  119. {
  120. fsql.GlobalFilter.Apply<ITenant>(FilterNames.Tenant, a => a.TenantId == user.TenantId);
  121. }
  122. return fsql;
  123. });
  124. //注册多数据库
  125. if (dbConfig.Dbs?.Length > 0)
  126. {
  127. foreach (var db in dbConfig.Dbs)
  128. {
  129. freeSqlCloud.Register(DbKeys.MultiDb + db.Key, () =>
  130. {
  131. #region FreeSql
  132. var freeSqlBuilder = new FreeSqlBuilder()
  133. .UseConnectionString(db.Type, db.ConnectionString, db.ProviderType.NotNull() ? Type.GetType(db.ProviderType) : null)
  134. .UseAutoSyncStructure(false)
  135. .UseLazyLoading(false)
  136. .UseNoneCommandParameter(true);
  137. hostAppOptions?.ConfigureFreeSqlBuilder?.Invoke(freeSqlBuilder);
  138. #region 监听所有命令
  139. if (dbConfig.MonitorCommand)
  140. {
  141. freeSqlBuilder.UseMonitorCommand(cmd => { }, (cmd, traceLog) =>
  142. {
  143. //Console.WriteLine($"{cmd.CommandText}\n{traceLog}\r\n");
  144. Console.WriteLine($"{cmd.CommandText}\r\n");
  145. });
  146. }
  147. #endregion 监听所有命令
  148. var fsql = freeSqlBuilder.Build();
  149. #region 监听Curd操作
  150. if (dbConfig.Curd)
  151. {
  152. fsql.Aop.CurdBefore += (s, e) =>
  153. {
  154. if (appConfig.MiniProfiler)
  155. {
  156. MiniProfiler.Current.CustomTiming("CurdBefore", e.Sql);
  157. }
  158. Console.WriteLine($"{e.Sql}\r\n");
  159. };
  160. fsql.Aop.CurdAfter += (s, e) =>
  161. {
  162. if (appConfig.MiniProfiler)
  163. {
  164. MiniProfiler.Current.CustomTiming("CurdAfter", $"{e.ElapsedMilliseconds}");
  165. }
  166. };
  167. }
  168. #endregion 监听Curd操作
  169. #endregion FreeSql
  170. return fsql;
  171. });
  172. }
  173. }
  174. }
  175. /// <summary>
  176. /// 添加TiDb数据库
  177. /// </summary>
  178. /// <param name="_"></param>
  179. /// <param name="context"></param>
  180. /// <param name="version">版本</param>
  181. public static void AddTiDb(this IServiceCollection _, HostAppContext context, string version = "8.0")
  182. {
  183. var dbConfig = ConfigHelper.Get<DbConfig>("dbconfig", context.Environment.EnvironmentName);
  184. var _dicMySqlVersion = typeof(FreeSqlGlobalExtensions).GetField("_dicMySqlVersion", BindingFlags.NonPublic | BindingFlags.Static);
  185. var dicMySqlVersion = new ConcurrentDictionary<string, string>();
  186. dicMySqlVersion[dbConfig.ConnectionString] = version;
  187. _dicMySqlVersion.SetValue(new ConcurrentDictionary<string, string>(), dicMySqlVersion);
  188. }
  189. }