v3.4.6
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF;
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar.Extensions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@@ -11,8 +12,7 @@ namespace SqlSugar;
|
||||
/// </summary>
|
||||
public class JNPFTenantExtensions
|
||||
{
|
||||
//public static IConfiguration _config { get; set; }
|
||||
private static ConnectionStringsOptions _connOpt { get; }
|
||||
public static IConfiguration _config { get; set; }
|
||||
|
||||
public static string skey = "Vl4WTqna9aZCgswjieIP";
|
||||
|
||||
@@ -21,8 +21,7 @@ public class JNPFTenantExtensions
|
||||
/// </summary>
|
||||
static JNPFTenantExtensions()
|
||||
{
|
||||
var config = new ConfigurationBuilder().AddJsonFile("Configurations/ConnectionStrings.json", true, true).Build();
|
||||
_connOpt = config.GetSection("ConnectionStrings").Get<ConnectionStringsOptions>();
|
||||
_config = new ConfigurationBuilder().Add(new JsonConfigurationSource { Path = "Configurations/ConnectionStrings.json", ReloadOnChange = true }).Build();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -33,14 +32,15 @@ public class JNPFTenantExtensions
|
||||
/// <returns></returns>
|
||||
public static ConnectionConfigOptions GetLinkToOrdinary(string configId, string tableName)
|
||||
{
|
||||
ConnectionStringsOptions conn = App.GetConfig<ConnectionStringsOptions>("ConnectionStrings", true);
|
||||
|
||||
List<DBConnectionConfig> configList = new List<DBConnectionConfig>();
|
||||
var connStr = string.Format(_connOpt.DefaultConnection, _connOpt.Host, _connOpt.Port, _connOpt.DBName, _connOpt.UserName, _connOpt.Password);
|
||||
configList.Add(new DBConnectionConfig()
|
||||
{
|
||||
IsMaster = true,
|
||||
ServiceName = tableName,
|
||||
dbType = ToDbType(_connOpt.DBType),
|
||||
connectionStr = DESCEncryption.Encrypt(connStr, skey)
|
||||
dbType = (DbType)Enum.Parse(typeof(DbType), conn.DBType),
|
||||
connectionStr = DESCEncryption.Encrypt(conn.ConnectString, skey)
|
||||
});
|
||||
return new ConnectionConfigOptions()
|
||||
{
|
||||
|
||||
15
common/Tnb.SqlSugar/Models/ITenantFilter.cs
Normal file
15
common/Tnb.SqlSugar/Models/ITenantFilter.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Extras.DatabaseAccessor.SqlSugar.Models;
|
||||
|
||||
/// <summary>
|
||||
/// 实体类基类.
|
||||
/// </summary>
|
||||
public interface ITenantFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// 租户id.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_TenantId", ColumnDescription = "租户id")]
|
||||
string TenantId { get; set; }
|
||||
}
|
||||
@@ -46,4 +46,6 @@ public sealed class ConnectionStringsOptions : IConfigurableOptions
|
||||
/// 默认数据库连接字符串.
|
||||
/// </summary>
|
||||
public string DefaultConnection { get; set; }
|
||||
|
||||
public string ConnectString { get { return string.Format(DefaultConnection, Host, Port, DBName, UserName, Password); } }
|
||||
}
|
||||
@@ -12,6 +12,11 @@ public sealed class TenantOptions : IConfigurableOptions
|
||||
/// </summary>
|
||||
public bool MultiTenancy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据隔离类型 SCHEMA:库隔离 COLUMN:字段隔离.
|
||||
/// </summary>
|
||||
public string MultiTenancyType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多租户数据接口.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using JNPF;
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar.Models;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.JsonSerialization;
|
||||
using JNPF.Logging;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace SqlSugar;
|
||||
|
||||
@@ -16,95 +16,98 @@ namespace SqlSugar;
|
||||
public partial class SqlSugarRepository<TEntity> : SimpleClient<TEntity>, ISqlSugarRepository<TEntity>
|
||||
where TEntity : class, new()
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public SqlSugarRepository(ISqlSugarClient context = null) : base(context)
|
||||
{
|
||||
// 获取数据库连接选项
|
||||
ConnectionStringsOptions connectionStrings = App.GetConfig<ConnectionStringsOptions>("ConnectionStrings", true);
|
||||
|
||||
// 获取多租户选项
|
||||
TenantOptions tenant = App.GetConfig<TenantOptions>("Tenant", true);
|
||||
var httpContext = App.HttpContext;
|
||||
|
||||
base.Context = (SqlSugarScope)context;
|
||||
|
||||
string tenantId = connectionStrings.ConfigId;
|
||||
|
||||
if (httpContext?.GetEndpoint()?.Metadata?.GetMetadata<AllowAnonymousAttribute>() == null || !string.IsNullOrEmpty(httpContext?.Request.Query["token"]))
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
public SqlSugarRepository(ISqlSugarClient context = null) : base(context)
|
||||
{
|
||||
if (tenant.MultiTenancy && httpContext != null)
|
||||
{
|
||||
var connectionConfig = new ConnectionConfigOptions();
|
||||
if (httpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
// 获取数据库连接选项
|
||||
ConnectionStringsOptions connectionStrings = App.GetConfig<ConnectionStringsOptions>("ConnectionStrings", true);
|
||||
|
||||
// 获取多租户选项
|
||||
TenantOptions tenant = App.GetConfig<TenantOptions>("Tenant", true);
|
||||
var httpContext = App.HttpContext;
|
||||
|
||||
base.Context = (SqlSugarScope)context;
|
||||
|
||||
string tenantId = connectionStrings.ConfigId;
|
||||
string tenantDbName = string.Empty;
|
||||
|
||||
if (httpContext?.GetEndpoint()?.Metadata?.GetMetadata<AllowAnonymousAttribute>() == null)
|
||||
{
|
||||
connectionConfig = JSON.Deserialize<ConnectionConfigOptions>(httpContext?.User.FindFirst("ConnectionConfig")?.Value);
|
||||
tenantId = connectionConfig.ConfigId;
|
||||
if (tenant.MultiTenancy && httpContext != null)
|
||||
{
|
||||
var connectionConfig = JSON.Deserialize<ConnectionConfigOptions>(httpContext?.User.FindFirst("ConnectionConfig")?.Value);
|
||||
tenantId = connectionConfig.ConfigId;
|
||||
tenantDbName = connectionConfig.ConfigList.FirstOrDefault().ServiceName;
|
||||
if (!base.Context.AsTenant().IsAnyConnection(connectionConfig.ConfigId))
|
||||
{
|
||||
base.Context.AsTenant().AddConnection(JNPFTenantExtensions.GetConfig(connectionConfig));
|
||||
}
|
||||
base.Context = base.Context.AsTenant().GetConnectionScope(connectionConfig.ConfigId);
|
||||
|
||||
if (!base.Context.Ado.IsValidConnection())
|
||||
{
|
||||
throw Oops.Oh("数据库连接错误");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Context = base.Context.AsTenant().GetConnectionScope(tenantId);
|
||||
}
|
||||
}
|
||||
else if (!httpContext.Request.Headers.ContainsKey("Authorization"))
|
||||
// 字段数据隔离
|
||||
if (!"default".Equals(tenantId) && tenant.MultiTenancyType.Equals("COLUMN"))
|
||||
{
|
||||
var token = Regex.Match(httpContext.Request.QueryString.Value, @"[?&]token=Bearer%20([\w\.-]+)($|&)").Groups[1].Value;
|
||||
var claims = JWTEncryption.ReadJwtToken(token.Replace("Bearer ", "").Replace("bearer ", ""))?.Claims;
|
||||
connectionConfig = JSON.Deserialize<ConnectionConfigOptions>(claims.FirstOrDefault(e => e.Type == "ConnectionConfig").Value);
|
||||
tenantId = connectionConfig.ConfigId;
|
||||
base.Context.QueryFilter.AddTableFilter<ITenantFilter>(it => it.TenantId == tenantDbName);
|
||||
base.Context.Aop.DataExecuting = (oldValue, entityInfo) =>
|
||||
{
|
||||
if (entityInfo.PropertyName == "TenantId" && entityInfo.OperationType == DataFilterType.InsertByObject)
|
||||
{
|
||||
entityInfo.SetValue(tenantDbName);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!base.Context.AsTenant().IsAnyConnection(connectionConfig.ConfigId))
|
||||
// 设置超时时间
|
||||
base.Context.Ado.CommandTimeOut = 30;
|
||||
base.Context.Aop.OnLogExecuted = (sql, pars) =>
|
||||
{
|
||||
base.Context.AsTenant().AddConnection(JNPFTenantExtensions.GetConfig(connectionConfig));
|
||||
}
|
||||
base.Context = base.Context.AsTenant().GetConnectionScope(connectionConfig.ConfigId);
|
||||
|
||||
if (!base.Context.Ado.IsValidConnection())
|
||||
{
|
||||
throw Oops.Oh("数据库连接错误");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Context = base.Context.AsTenant().GetConnectionScope(tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置超时时间
|
||||
base.Context.Ado.CommandTimeOut = 30;
|
||||
base.Context.Aop.OnLogExecuted = (sql, pars) =>
|
||||
{
|
||||
var oldColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
var finalSql = UtilMethods.GetSqlString(Context.CurrentConnectionConfig.DbType, sql, pars);
|
||||
Console.WriteLine($"【{DateTime.Now.ToString("HH:mm:ss.fff")}——SQL执行完成】{Context.Ado.SqlExecutionTime.TotalMilliseconds} ms");
|
||||
Console.WriteLine(finalSql);
|
||||
Console.ForegroundColor = oldColor;
|
||||
if (Context.Ado.SqlExecutionTime.TotalMilliseconds > 3000)
|
||||
{
|
||||
Log.Warning($"慢查询: {Context.Ado.SqlExecutionTime.TotalMilliseconds}ms, SQL: " + finalSql);
|
||||
}
|
||||
Console.WriteLine();
|
||||
//App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + base.Context.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
|
||||
};
|
||||
base.Context.Aop.OnError = (ex) =>
|
||||
{
|
||||
Log.Error("SQL执行错误: " + UtilMethods.GetSqlString(base.Context.CurrentConnectionConfig.DbType, ex.Sql, (SugarParameter[])ex.Parametres));
|
||||
//App.PrintToMiniProfiler("SqlSugar", "Error", $"{ex.Message}{Environment.NewLine}{ex.Sql}{pars}{Environment.NewLine}");
|
||||
};
|
||||
|
||||
if (base.Context.CurrentConnectionConfig.DbType == DbType.Oracle)
|
||||
{
|
||||
base.Context.Aop.OnExecutingChangeSql = (sql, pars) =>
|
||||
{
|
||||
if (pars != null)
|
||||
{
|
||||
foreach (var item in pars)
|
||||
{
|
||||
//如果是DbTppe=string设置成OracleDbType.Nvarchar2
|
||||
item.IsNvarchar2 = true;
|
||||
}
|
||||
var oldColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
var finalSql = UtilMethods.GetSqlString(Context.CurrentConnectionConfig.DbType, sql, pars);
|
||||
Console.WriteLine($"【{DateTime.Now.ToString("HH:mm:ss.fff")}——SQL执行完成】{Context.Ado.SqlExecutionTime.TotalMilliseconds} ms");
|
||||
Console.WriteLine(finalSql);
|
||||
Console.ForegroundColor = oldColor;
|
||||
if (Context.Ado.SqlExecutionTime.TotalMilliseconds > 3000)
|
||||
{
|
||||
Log.Warning($"慢查询: {Context.Ado.SqlExecutionTime.TotalMilliseconds}ms, SQL: " + finalSql);
|
||||
}
|
||||
Console.WriteLine();
|
||||
//App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + base.Context.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value)));
|
||||
};
|
||||
return new KeyValuePair<string, SugarParameter[]>(sql, pars);
|
||||
};
|
||||
base.Context.Aop.OnError = (ex) =>
|
||||
{
|
||||
Log.Error("SQL执行错误: " + UtilMethods.GetSqlString(base.Context.CurrentConnectionConfig.DbType, ex.Sql, (SugarParameter[])ex.Parametres));
|
||||
//App.PrintToMiniProfiler("SqlSugar", "Error", $"{ex.Message}{Environment.NewLine}{ex.Sql}{pars}{Environment.NewLine}");
|
||||
};
|
||||
|
||||
|
||||
if (base.Context.CurrentConnectionConfig.DbType == DbType.Oracle)
|
||||
{
|
||||
base.Context.Aop.OnExecutingChangeSql = (sql, pars) =>
|
||||
{
|
||||
if (pars != null)
|
||||
{
|
||||
foreach (var item in pars)
|
||||
{
|
||||
//如果是DbTppe=string设置成OracleDbType.Nvarchar2
|
||||
item.IsNvarchar2 = true;
|
||||
}
|
||||
};
|
||||
return new KeyValuePair<string, SugarParameter[]>(sql, pars);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.73" />
|
||||
<PackageReference Include="Tnb.Core" Version="2023.3.24.1010" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.77" />
|
||||
<PackageReference Include="Tnb.Core" Version="2023.5.25.958" />
|
||||
<!--<ProjectReference Include="..\..\..\Tnb.Core\Tnb.Core\Tnb.Core.csproj" />-->
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user