仓储+多租户 用法 请教 返回
看文档 是
//方式1:通过Config获取数据库,比较灵活
var
db1=db.GetConnection(configId)
//非线程安全 (性能好)
var
db1=db.GetConnectionScope(configId);
//线程安全 (解决大部线程安全,性能有些损耗)
//方式2:通过特性获取数据库,一个实体对一个库的时候非常方便
var
db2=db.GetConnectionWithAttr<T>()
//非线程安全 (性能好)
var
db2=db.GetConnectionScopeWithAttr<T>()
//线程安全 (解决大部线程安全,性能有些损耗)
[TenantAttribute(
"1"
)]
//对应ConfigId=1
public
class
C1Table
{
public
string
Id {
get
;
set
; }
}
SqlSugarScopeProvider GetConnectionScopeWithAttr<T>(); 返回 一个 SqlSugarScopeProvider 这些方法 都得 手动获取 数据库连接 感觉相当于手动切换数据库,有没有办法 如果 我在实体设置了TenantAttribute 就自动 像正常仓储 那样 使用正常 仓库的 方法 的sqlSugarClient 和SqlSugarScope 呢?比如说 可以直接 像下面那样写
private readonly ISqlSugarRepository<XxxEntity> _repository;
public XxxService(
ISqlSugarRepository<SynThirdInfoEntity> repository)
{
_repository = repository;
}
private async Task<dynamic> Task Test()
{
await _repository.AsSugarClient().Queryable<XxxEntity>().Where(x => x.DeleteMark == null).ToListAsync();
}
热忱回答(4)
-
fate sta VIP01个月前
这要看仓储怎么写
0 回复 -
fate sta VIP01个月前
文档:多租户+仓储
0 回复 -
梁山好汉 VIP01个月前
@fate sta:看了 我的问题是 现在的写法都是要手动,都得 手动获取 数据库连接 感觉相当于手动切换数据库,
有没有办法实现 只要我 我在实体设置了TenantAttribute ,注入仓储时 就自动切换 ,不用写GetConnectionWithAttr 等,如同 普通主库仓储 那样 使用正常 仓库的 方法 的sqlSugarClient 和SqlSugarScope 呢?
0 回复 -
梁山好汉 VIP01个月前
@fate sta:我写了一个 这样 的 方法 实现无感自动切换数据库,不知道这样是否妥当 然后 service 只需要 注入 ISqlSugarRepository<XxxEntity> repository 即可以直接使用,还请 不吝赐教,我不知道这样做从设计上是否妥当,不知道为何 ,sqlsugar没有实现这个功能
/// <summary> /// SqlSugar 仓储实现类 /// </summary> /// <typeparam name="TEntity"></typeparam> public partial class SqlSugarRepository<TEntity> : SimpleClient<TEntity>, ISqlSugarRepository<TEntity> where TEntity : class, new() { /// <summary> /// 构造函数 /// </summary> public SqlSugarRepository(IServiceProvider serviceProvider, ISqlSugarClient context = null) : base(context) { using var serviceScope = serviceProvider.CreateScope(); var _cacheManager = serviceScope.ServiceProvider.GetService<ICacheManager>(); // 获取数据库连接选项 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.DefaultConnectionConfig.ConfigId.ToString(); string tenantDbName = string.Empty; if (httpContext?.GetEndpoint()?.Metadata?.GetMetadata<AllowAnonymousAttribute>() == null) { if (tenant.MultiTenancy && httpContext != null) { tenantId = httpContext?.User.FindFirst("TenantId")?.Value; var tenantCache = _cacheManager.Get<List<GlobalTenantCacheModel>>("lydc:global:tenant").Find(it => it.TenantId.Equals(tenantId)); if (tenantCache != null) { if (!base.Context.AsTenant().IsAnyConnection(tenantCache.connectionConfig.ConfigId)) { base.Context.AsTenant().AddConnection(LYDCTenantExtensions.GetConfig(tenantCache.connectionConfig)); } base.Context = base.Context.AsTenant().GetConnectionScope(tenantCache.connectionConfig.ConfigId); // 字段隔离追加过滤器 if (tenantCache.type == 1) { tenantDbName = tenantCache.connectionConfig.IsolationField; if (!"default".Equals(tenantId)) { base.Context.QueryFilter.Clear(); 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 (entityInfo.PropertyName == "TenantId" && entityInfo.OperationType == DataFilterType.UpdateByObject) { entityInfo.SetValue(tenantDbName); } if (entityInfo.PropertyName == "TenantId" && entityInfo.OperationType == DataFilterType.DeleteByObject) { entityInfo.SetValue(tenantDbName); } }; } } if (!base.Context.Ado.IsValidConnection()) { throw Oops.Oh("数据库连接错误"); } } } else { Console.WriteLine($"切换 tenantId:{tenantId}"); base.Context = base.Context.AsTenant().GetConnectionScope(tenantId); } } //实现无感自动切换数据库 var tenantAttribute = typeof(TEntity).GetCustomAttribute<TenantAttribute>(); Console.WriteLine($"TEntity:{typeof(TEntity).Name} configId:{tenantAttribute?.configId}"); if (tenantAttribute != null) { var configId = tenantAttribute.configId; if (tenantAttribute.configId != null && !tenantAttribute.configId.ToString().Equals(tenantId) && base.Context.AsTenant().IsAnyConnection(configId)) { Console.WriteLine($"实现切换 tenantId:{tenantId}"); base.Context = base.Context.AsTenant().GetConnectionScope(configId); } } // 设置超时时间 base.Context.Ado.CommandTimeOut = 30; base.Context.Aop.OnLogExecuting = (sql, pars) => { if (sql.StartsWith("SELECT", StringComparison.OrdinalIgnoreCase)) Console.ForegroundColor = ConsoleColor.Green; if (sql.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase) || sql.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase)) Console.ForegroundColor = ConsoleColor.White; if (sql.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase)) Console.ForegroundColor = ConsoleColor.Blue; // 在控制台输出sql语句 Console.WriteLine("【" + DateTime.Now + "——执行SQL】\r\n" + UtilMethods.GetSqlString(base.Context.CurrentConnectionConfig.DbType, sql, pars) + "\r\n"); //App.PrintToMiniProfiler("SqlSugar", "Info", sql + "\r\n" + base.Context.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); }; base.Context.Aop.OnError = (ex) => { Console.ForegroundColor = ConsoleColor.Red; var pars = base.Context.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value)); Console.WriteLine("【" + DateTime.Now + "——错误SQL】\r\n" + UtilMethods.GetSqlString(base.Context.CurrentConnectionConfig.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n"); //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); }; } } }
0 回复