SqlSugarStartupExtensions.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System.ComponentModel;
  2. using System.ComponentModel.DataAnnotations;
  3. using Microsoft.Extensions.Configuration;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using Serilog;
  6. using SqlSugar;
  7. using XF.Domain.Entities;
  8. using XF.Domain.Extensions;
  9. using XF.Utility.SequentialId;
  10. namespace Hotline.Repository.SqlSugar
  11. {
  12. public static class SqlSugarStartupExtensions
  13. {
  14. public static void AddSqlSugar(this IServiceCollection services, IConfiguration configuration, string dbName = "CallCenter")
  15. {
  16. //多租户 new SqlSugarScope(List<ConnectionConfig>,db=>{});
  17. SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
  18. {
  19. DbType = DbType.MySql,
  20. ConnectionString = configuration.GetConnectionString(dbName),
  21. IsAutoCloseConnection = true,
  22. ConfigureExternalServices = new ConfigureExternalServices
  23. {
  24. EntityService = (property, column) =>
  25. {
  26. var attributes = property.GetCustomAttributes(true);//get all attributes
  27. //if (attributes.Any(it => it is KeyAttribute))// by attribute set primarykey
  28. //{
  29. // column.IsPrimarykey = true; //有哪些特性可以看 1.2 特性明细
  30. //}
  31. ////可以写多个,这边可以断点调试
  32. //// if (attributes.Any(it => it is NotMappedAttribute))
  33. ////{
  34. //// column.IsIgnore= true;
  35. ////}
  36. //if (attributes.Any(it => it is DbNullableAttribute))
  37. //{
  38. // column.IsNullable = true;
  39. //}
  40. //if (attributes.Any(it => it is DbJsonAttribute))
  41. //{
  42. // column.DataType = "varchar(3000)";
  43. // column.IsJson = true;
  44. //}
  45. //if (attributes.Any(it => it is DbLengthAttribute))
  46. //{
  47. // column.Length = (attributes.First(d => d is DbLengthAttribute) as DbLengthAttribute)?.MaxLength ?? 255;
  48. //}
  49. //if (attributes.Any(it => it is DbIgnoreAttribute))
  50. //{
  51. // column.IsIgnore = true;
  52. //}
  53. if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
  54. {
  55. column.IsNullable = true;
  56. }
  57. if (column.PropertyName.ToLower() == "id" || attributes.Any(it => it is KeyAttribute)) //是id的设为主键
  58. {
  59. column.IsPrimarykey = true;
  60. column.Length = 36;
  61. }
  62. //column.ColumnDescription = (attributes.FirstOrDefault(d => d is DescriptionAttribute) as DescriptionAttribute)?.Description ?? string.Empty;
  63. },
  64. EntityNameService = (type, entity) =>
  65. {
  66. var attributes = type.GetCustomAttributes(true);
  67. //if (attributes.Any(it => it is TableAttribute))
  68. //{
  69. // entity.DbTableName = (attributes.First(it => it is TableAttribute) as TableAttribute).UserName;
  70. //}
  71. entity.DbTableName = entity.DbTableName.ToSnakeCase();
  72. if (attributes.Any(d => d is DescriptionAttribute))
  73. {
  74. entity.TableDescription =
  75. (attributes.First(d => d is DescriptionAttribute) as DescriptionAttribute).Description;
  76. }
  77. }
  78. }
  79. },
  80. db =>
  81. {
  82. /***写AOP等方法***/
  83. db.Aop.OnLogExecuting = (sql, pars) =>
  84. {
  85. //Log.Information(sql);
  86. };
  87. db.Aop.OnError = (exp) =>//SQL报错
  88. {
  89. //exp.sql 这样可以拿到错误SQL,性能无影响拿到ORM带参数使用的SQL
  90. Log.Error("SqlError: {0}", exp.Sql);
  91. //5.0.8.2 获取无参数化 SQL 对性能有影响,特别大的SQL参数多的,调试使用
  92. //UtilMethods.GetSqlString(DbType.SqlServer,exp.sql,exp.parameters)
  93. };
  94. db.Aop.OnExecutingChangeSql = (sql, pars) => //可以修改SQL和参数的值
  95. {
  96. //sql=newsql
  97. //foreach(var p in pars) //修改
  98. return new KeyValuePair<string, SugarParameter[]>(sql, pars);
  99. };
  100. db.Aop.OnLogExecuted = (sql, p) =>
  101. {
  102. //执行时间超过1秒
  103. if (db.Ado.SqlExecutionTime.TotalSeconds > 1)
  104. {
  105. //代码CS文件名
  106. var fileName = db.Ado.SqlStackTrace.FirstFileName;
  107. //代码行数
  108. var fileLine = db.Ado.SqlStackTrace.FirstLine;
  109. //方法名
  110. var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName;
  111. //db.Ado.SqlStackTrace.MyStackTraceList[1].xxx 获取上层方法的信息
  112. Log.Warning("slow query ==> fileName: {fileName}, fileLine: {fileLine}, FirstMethodName: {FirstMethodName}",
  113. fileName, fileLine, FirstMethodName);
  114. }
  115. //相当于EF的 PrintToMiniProfiler
  116. };
  117. db.Aop.DataExecuting = (oldValue, entityInfo) =>
  118. {
  119. //inset生效
  120. if (entityInfo.PropertyName == "CreationTime" && entityInfo.OperationType == DataFilterType.InsertByObject)
  121. {
  122. entityInfo.SetValue(DateTime.Now);//修改CreateTime字段
  123. //entityInfo有字段所有参数
  124. }
  125. //update生效
  126. else if (entityInfo.PropertyName == "LastModificationTime" && entityInfo.OperationType == DataFilterType.UpdateByObject)
  127. {
  128. entityInfo.SetValue(DateTime.Now);//修改UpdateTime字段
  129. }
  130. //根据当前列修改另一列 可以么写
  131. //if(当前列逻辑==XXX)
  132. //var properyDate = entityInfo.EntityValue.GetType().GetProperty("Date");
  133. //if(properyDate!=null)
  134. //properyDate.SetValue(entityInfo.EntityValue,1);
  135. else if (entityInfo.EntityColumnInfo.IsPrimarykey
  136. && entityInfo.EntityColumnInfo.PropertyName.ToLower() == "id"
  137. && entityInfo.OperationType == DataFilterType.InsertByObject) //通过主键保证只进一次事件
  138. {
  139. var propertyId = entityInfo.EntityValue.GetType().GetProperty("Id");
  140. if (propertyId is not null)
  141. {
  142. var idValue = propertyId.GetValue(entityInfo.EntityValue);
  143. if (idValue is null)
  144. //这样每条记录就只执行一次
  145. entityInfo.SetValue(SequentialStringGenerator.Create());
  146. }
  147. }
  148. };
  149. });
  150. ISugarUnitOfWork<HotlineDbContext> context = new SugarUnitOfWork<HotlineDbContext>(sqlSugar);
  151. ////全局过滤
  152. //var deletionTypes = AppDomain.CurrentDomain.GetAssemblies().ToList()
  153. // .SelectMany(d=>d.GetTypes()).Where(d=>d.GetInterfaces()/*.Any(x=>x == typeof(ISoftDelete))*/);//todo 找出即实现ISoftDelete 又实现IEntity
  154. //foreach (var deletionType in deletionTypes)
  155. //{
  156. //}
  157. services.AddSingleton<ISugarUnitOfWork<HotlineDbContext>>(context);
  158. }
  159. }
  160. }