using System.ComponentModel; using System.ComponentModel.DataAnnotations; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Serilog; using SqlSugar; using XF.Domain.Entities; using XF.Domain.Extensions; using XF.Utility.SequentialId; namespace Hotline.Repository.SqlSugar { public static class SqlSugarStartupExtensions { public static void AddSqlSugar(this IServiceCollection services, IConfiguration configuration, string dbName = "CallCenter") { //多租户 new SqlSugarScope(List,db=>{}); SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig() { DbType = DbType.MySql, ConnectionString = configuration.GetConnectionString(dbName), IsAutoCloseConnection = true, ConfigureExternalServices = new ConfigureExternalServices { EntityService = (property, column) => { var attributes = property.GetCustomAttributes(true);//get all attributes //if (attributes.Any(it => it is KeyAttribute))// by attribute set primarykey //{ // column.IsPrimarykey = true; //有哪些特性可以看 1.2 特性明细 //} ////可以写多个,这边可以断点调试 //// if (attributes.Any(it => it is NotMappedAttribute)) ////{ //// column.IsIgnore= true; ////} //if (attributes.Any(it => it is DbNullableAttribute)) //{ // column.IsNullable = true; //} //if (attributes.Any(it => it is DbJsonAttribute)) //{ // column.DataType = "varchar(3000)"; // column.IsJson = true; //} //if (attributes.Any(it => it is DbLengthAttribute)) //{ // column.Length = (attributes.First(d => d is DbLengthAttribute) as DbLengthAttribute)?.MaxLength ?? 255; //} //if (attributes.Any(it => it is DbIgnoreAttribute)) //{ // column.IsIgnore = true; //} if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) { column.IsNullable = true; } if (column.PropertyName.ToLower() == "id" || attributes.Any(it => it is KeyAttribute)) //是id的设为主键 { column.IsPrimarykey = true; column.Length = 36; } //column.ColumnDescription = (attributes.FirstOrDefault(d => d is DescriptionAttribute) as DescriptionAttribute)?.Description ?? string.Empty; }, EntityNameService = (type, entity) => { var attributes = type.GetCustomAttributes(true); //if (attributes.Any(it => it is TableAttribute)) //{ // entity.DbTableName = (attributes.First(it => it is TableAttribute) as TableAttribute).UserName; //} entity.DbTableName = entity.DbTableName.ToSnakeCase(); if (attributes.Any(d => d is DescriptionAttribute)) { entity.TableDescription = (attributes.First(d => d is DescriptionAttribute) as DescriptionAttribute).Description; } } } }, db => { /***写AOP等方法***/ db.Aop.OnLogExecuting = (sql, pars) => { //Log.Information(sql); }; db.Aop.OnError = (exp) =>//SQL报错 { //exp.sql 这样可以拿到错误SQL,性能无影响拿到ORM带参数使用的SQL Log.Error("SqlError: {0}", exp.Sql); //5.0.8.2 获取无参数化 SQL 对性能有影响,特别大的SQL参数多的,调试使用 //UtilMethods.GetSqlString(DbType.SqlServer,exp.sql,exp.parameters) }; db.Aop.OnExecutingChangeSql = (sql, pars) => //可以修改SQL和参数的值 { //sql=newsql //foreach(var p in pars) //修改 return new KeyValuePair(sql, pars); }; db.Aop.OnLogExecuted = (sql, p) => { //执行时间超过1秒 if (db.Ado.SqlExecutionTime.TotalSeconds > 1) { //代码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 获取上层方法的信息 Log.Warning("slow query ==> fileName: {fileName}, fileLine: {fileLine}, FirstMethodName: {FirstMethodName}", fileName, fileLine, FirstMethodName); } //相当于EF的 PrintToMiniProfiler }; db.Aop.DataExecuting = (oldValue, entityInfo) => { //inset生效 if (entityInfo.PropertyName == "CreationTime" && entityInfo.OperationType == DataFilterType.InsertByObject) { entityInfo.SetValue(DateTime.Now);//修改CreateTime字段 //entityInfo有字段所有参数 } //update生效 else if (entityInfo.PropertyName == "LastModificationTime" && entityInfo.OperationType == DataFilterType.UpdateByObject) { entityInfo.SetValue(DateTime.Now);//修改UpdateTime字段 } //根据当前列修改另一列 可以么写 //if(当前列逻辑==XXX) //var properyDate = entityInfo.EntityValue.GetType().GetProperty("Date"); //if(properyDate!=null) //properyDate.SetValue(entityInfo.EntityValue,1); else if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyName.ToLower() == "id" && entityInfo.OperationType == DataFilterType.InsertByObject) //通过主键保证只进一次事件 { var propertyId = entityInfo.EntityValue.GetType().GetProperty("Id"); if (propertyId is not null) { var idValue = propertyId.GetValue(entityInfo.EntityValue); if (idValue is null) //这样每条记录就只执行一次 entityInfo.SetValue(SequentialStringGenerator.Create()); } } }; }); ISugarUnitOfWork context = new SugarUnitOfWork(sqlSugar); ////全局过滤 //var deletionTypes = AppDomain.CurrentDomain.GetAssemblies().ToList() // .SelectMany(d=>d.GetTypes()).Where(d=>d.GetInterfaces()/*.Any(x=>x == typeof(ISoftDelete))*/);//todo 找出即实现ISoftDelete 又实现IEntity //foreach (var deletionType in deletionTypes) //{ //} services.AddSingleton>(context); } } }