using EntrustSettle.Common;
using EntrustSettle.Common.Caches;
using EntrustSettle.Common.DB;
using EntrustSettle.Common.DB.Aop;
using EntrustSettle.Model;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Yitter.IdGenerator;
namespace EntrustSettle.Extensions
{
///
/// SqlSugar 启动服务
///
public static class SqlsugarSetup
{
public static void AddSqlsugarSetup(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));
// 使用自定义的雪花Id算法,程序启动时执行一次就行
StaticConfig.CustomSnowFlakeFunc = YitIdHelper.NextId;
// 默认添加主数据库连接
if (!AppSettings.app("MainDB").IsNullOrEmpty())
{
DBConst.MainDbConfigId = AppSettings.app("MainDB");
}
BaseDBConfig.MutiConnectionString.allDbs.ForEach(m =>
{
var config = new ConnectionConfig()
{
ConfigId = m.ConnId.ObjToString().ToLower(),
ConnectionString = m.Connection,
DbType = (DbType)m.DbType,
IsAutoCloseConnection = true,
// Check out more information: https://github.com/anjoy8/EntrustSettle/issues/122
//IsShardSameThread = false,
MoreSettings = new ConnMoreSettings()
{
//IsWithNoLockQuery = true,
IsAutoRemoveDataCache = true,
SqlServerCodeFirstNvarchar = true,
},
// 从库
SlaveConnectionConfigs = m.Slaves?.Where(s => s.HitRate > 0).Select(s => new SlaveConnectionConfig
{
ConnectionString = s.Connection,
HitRate = s.HitRate
}).ToList(),
// 自定义特性
ConfigureExternalServices = new ConfigureExternalServices()
{
DataInfoCacheService = new SqlSugarCacheService(),
EntityService = (property, column) =>
{
if (column.IsPrimarykey && property.PropertyType == typeof(int))
{
column.IsIdentity = true;
}
// 为long?/Datetime?等可为Null的类型以及String,统一设置IsNullable=true
if (column.IsPrimarykey == false &&
(column.PropertyInfo.PropertyType == typeof(string) || Nullable.GetUnderlyingType(column.PropertyInfo.PropertyType) != null))
{
column.IsNullable = true;
}
}
},
InitKeyType = InitKeyType.Attribute
};
if (DBConst.LogDbConfigId.ToLower().Equals(m.ConnId.ToLower()))
{
BaseDBConfig.LogConfig = config;
}
else
{
if (string.Equals(config.ConfigId, DBConst.MainDbConfigId,
StringComparison.CurrentCultureIgnoreCase))
{
BaseDBConfig.MainConfig = config;
}
else if (m.ConnId.ToLower().StartsWith(DBConst.MainDbConfigId.ToLower()))
{
//复用连接
BaseDBConfig.ReuseConfigs.Add(config);
}
BaseDBConfig.ValidConfig.Add(config);
}
BaseDBConfig.AllConfigs.Add(config);
});
if (AppSettings.app("AppSettings", "LogToDb").ObjToBool() && BaseDBConfig.LogConfig is null)
{
throw new ApplicationException("未配置Log库连接");
}
// SqlSugarScope是线程安全,可使用单例注入
// 参考:https://www.donet5.com/Home/Doc?typeId=1181
services.AddSingleton(o =>
{
return new SqlSugarScope(BaseDBConfig.AllConfigs, db =>
{
BaseDBConfig.ValidConfig.ForEach(config =>
{
var dbProvider = db.GetConnectionScope((string)config.ConfigId);
// 打印SQL语句
dbProvider.Aop.OnLogExecuting = (s, parameters) =>
{
SqlSugarAop.OnLogExecuting(sql: s,
param: parameters,
path: App.HttpContext?.Request?.Path,
user: App.User?.Name?.ObjToString(),
traceId: App.HttpContext?.TraceIdentifier);
};
// 数据初始化
dbProvider.Aop.DataExecuting = SqlSugarAop.DataExecuting;
// 配置实体假删除过滤器
RepositorySetting.SetDeletedEntityFilter(dbProvider);
// 这里不需要用到租户
// RepositorySetting.SetTenantEntityFilter(dbProvider);
});
//故障转移,检查主库链接自动切换备用连接
SqlSugarReuse.AutoChangeAvailableConnect(db);
});
});
}
private static string ExtractTableName(string sql)
{
// 匹配 SQL 语句中的表名的正则表达式
//string regexPattern = @"\s*(?:UPDATE|DELETE\s+FROM|SELECT\s+\*\s+FROM)\s+(\w+)";
string regexPattern = @"(?i)(?:FROM|UPDATE|DELETE\s+FROM)\s+`(.+?)`";
Regex regex = new Regex(regexPattern, RegexOptions.IgnoreCase);
Match match = regex.Match(sql);
if (match.Success)
{
// 提取匹配到的表名
return match.Groups[1].Value;
}
else
{
// 如果没有匹配到表名,则返回空字符串或者抛出异常等处理
return string.Empty;
}
}
}
}