DBServiceCollectionExtensions.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. #region 全局过滤器
  65. //软删除过滤器
  66. fsql.GlobalFilter.Apply<ISoftDelete>(FilterNames.SoftDelete, a => a.IsDeleted == false);
  67. //租户过滤器
  68. if (appConfig.Tenant)
  69. {
  70. fsql.GlobalFilter.Apply<ITenant>(FilterNames.Tenant, a => a.TenantId == user.TenantId);
  71. }
  72. #endregion
  73. //配置实体
  74. DbHelper.ConfigEntity(fsql, appConfig);
  75. hostAppOptions?.ConfigureFreeSql?.Invoke(fsql);
  76. #region 初始化数据库
  77. //同步结构
  78. if (dbConfig.SyncStructure)
  79. {
  80. DbHelper.SyncStructure(fsql, dbConfig: dbConfig, appConfig: appConfig);
  81. }
  82. #region 审计数据
  83. //计算服务器时间
  84. var selectProvider = fsql.Select<object>() as Select0Provider;
  85. var serverTime = fsql.Select<object>().WithSql($"select {selectProvider._commonUtils.NowUtc} a").First(a => Convert.ToDateTime("a"));
  86. var timeOffset = DateTime.UtcNow.Subtract(serverTime);
  87. DbHelper.TimeOffset = timeOffset;
  88. fsql.Aop.AuditValue += (s, e) =>
  89. {
  90. DbHelper.AuditValue(e, timeOffset, user);
  91. };
  92. #endregion 审计数据
  93. //同步数据
  94. if (dbConfig.SyncData)
  95. {
  96. DbHelper.SyncDataAsync(fsql, dbConfig, appConfig).Wait();
  97. }
  98. #endregion 初始化数据库
  99. //生成数据
  100. if (dbConfig.GenerateData && !dbConfig.CreateDb && !dbConfig.SyncData)
  101. {
  102. DbHelper.GenerateDataAsync(fsql, appConfig).Wait();
  103. }
  104. #region 监听Curd操作
  105. if (dbConfig.Curd)
  106. {
  107. fsql.Aop.CurdBefore += (s, e) =>
  108. {
  109. if (appConfig.MiniProfiler)
  110. {
  111. MiniProfiler.Current.CustomTiming("CurdBefore", e.Sql);
  112. }
  113. Console.WriteLine($"{e.Sql}\r\n");
  114. };
  115. fsql.Aop.CurdAfter += (s, e) =>
  116. {
  117. if (appConfig.MiniProfiler)
  118. {
  119. MiniProfiler.Current.CustomTiming("CurdAfter", $"{e.ElapsedMilliseconds}");
  120. }
  121. };
  122. }
  123. #endregion 监听Curd操作
  124. return fsql;
  125. });
  126. //注册多数据库
  127. if (dbConfig.Dbs?.Length > 0)
  128. {
  129. foreach (var db in dbConfig.Dbs)
  130. {
  131. freeSqlCloud.Register(DbKeys.MultiDb + db.Key, () =>
  132. {
  133. #region FreeSql
  134. var freeSqlBuilder = new FreeSqlBuilder()
  135. .UseConnectionString(db.Type, db.ConnectionString, db.ProviderType.NotNull() ? Type.GetType(db.ProviderType) : null)
  136. .UseAutoSyncStructure(false)
  137. .UseLazyLoading(false)
  138. .UseNoneCommandParameter(true);
  139. hostAppOptions?.ConfigureFreeSqlBuilder?.Invoke(freeSqlBuilder);
  140. #region 监听所有命令
  141. if (dbConfig.MonitorCommand)
  142. {
  143. freeSqlBuilder.UseMonitorCommand(cmd => { }, (cmd, traceLog) =>
  144. {
  145. //Console.WriteLine($"{cmd.CommandText}\n{traceLog}\r\n");
  146. Console.WriteLine($"{cmd.CommandText}\r\n");
  147. });
  148. }
  149. #endregion 监听所有命令
  150. var fsql = freeSqlBuilder.Build();
  151. #region 监听Curd操作
  152. if (dbConfig.Curd)
  153. {
  154. fsql.Aop.CurdBefore += (s, e) =>
  155. {
  156. if (appConfig.MiniProfiler)
  157. {
  158. MiniProfiler.Current.CustomTiming("CurdBefore", e.Sql);
  159. }
  160. Console.WriteLine($"{e.Sql}\r\n");
  161. };
  162. fsql.Aop.CurdAfter += (s, e) =>
  163. {
  164. if (appConfig.MiniProfiler)
  165. {
  166. MiniProfiler.Current.CustomTiming("CurdAfter", $"{e.ElapsedMilliseconds}");
  167. }
  168. };
  169. }
  170. #endregion 监听Curd操作
  171. #endregion FreeSql
  172. return fsql;
  173. });
  174. }
  175. }
  176. }
  177. /// <summary>
  178. /// 添加TiDb数据库
  179. /// </summary>
  180. /// <param name="_"></param>
  181. /// <param name="context"></param>
  182. /// <param name="version">版本</param>
  183. public static void AddTiDb(this IServiceCollection _, HostAppContext context, string version = "8.0")
  184. {
  185. var dbConfig = ConfigHelper.Get<DbConfig>("dbconfig", context.Environment.EnvironmentName);
  186. var _dicMySqlVersion = typeof(FreeSqlGlobalExtensions).GetField("_dicMySqlVersion", BindingFlags.NonPublic | BindingFlags.Static);
  187. var dicMySqlVersion = new ConcurrentDictionary<string, string>();
  188. dicMySqlVersion[dbConfig.ConnectionString] = version;
  189. _dicMySqlVersion.SetValue(new ConcurrentDictionary<string, string>(), dicMySqlVersion);
  190. }
  191. }