仓储+多租户 用法 请教 返回

SqlSugar 沟通中
4 223

看文档 是

   //方式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 { getset; }
    }

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 fate sta VIP0
    1个月前

    这要看仓储怎么写

    0 回复
  • fate sta fate sta VIP0
    1个月前

    文档:多租户+仓储

    0 回复
  • @fate sta:看了 我的问题是 现在的写法都是要手动,都得 手动获取 数据库连接 感觉相当于手动切换数据库,

    有没有办法实现 只要我 我在实体设置了TenantAttribute  ,注入仓储时 就自动切换 ,不用写GetConnectionWithAttr   等,如同  普通主库仓储 那样 使用正常 仓库的 方法 的sqlSugarClient 和SqlSugarScope 呢?

    0 回复
  • @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 回复