/// <summary>
    /// 对存取器的数据库分片。
    /// </summary>
    /// <param name="shardingManager">给定的 <see cref="IShardingManager"/>。</param>
    /// <param name="accessor">给定的 <see cref="IAccessor"/>。</param>
    /// <param name="descriptor">输出 <see cref="ShardedDescriptor"/>。</param>
    /// <returns>返回 <see cref="IAccessor"/>。</returns>
    public static IAccessor ShardDatabase(this IShardingManager shardingManager, IAccessor accessor,
                                          [MaybeNullWhen(false)] out ShardedDescriptor descriptor)
    {
        var attribute = accessor.AccessorDescriptor?.Sharded;

        if (attribute is null)
        {
            descriptor = null;
            return(accessor);
        }

        descriptor = shardingManager.CreateDescriptor(attribute);

        descriptor.DefaultStrategy?.FormatSuffix(descriptor);

        var shardedName = descriptor.ToString();

        if (!shardedName.Equals(descriptor.BaseName, StringComparison.Ordinal))
        {
            var newConnectionString = accessor.CurrentConnectionString !
                                      .Replace(attribute.BaseName !, shardedName);

            accessor.ChangeConnection(newConnectionString);
        }

        return(accessor);
    }
    public InternalAccessorManager(IOptionsMonitor <DataExtensionOptions> optionsMonitor,
                                   IAccessorMigrator migrator, IAccessorResolver resolver, IShardingManager shardingManager)
    {
        _optionsMonitor  = optionsMonitor;
        _migrator        = migrator;
        _shardingManager = shardingManager;

        Accessors = resolver.ResolveAccessors();
        if (Accessors.Count < 1)
        {
            throw new ArgumentNullException($"The accessors not found, verify that accessor extensions are registered. ex. \"services.AddDbContext<TContext>(opts => opts.UseXXX<Database>().UseAccessor());\"");
        }
    }
    /// <summary>
    /// 对实体映射的数据表分片。
    /// </summary>
    /// <param name="manager">给定的 <see cref="IShardingManager"/>。</param>
    /// <param name="entityType">给定的实体类型。</param>
    /// <param name="entity">给定的实体对象。</param>
    /// <param name="tableName">给定的表名。</param>
    /// <returns>返回 <see cref="ShardedDescriptor"/>。</returns>
    public static ShardedDescriptor ShardEntity(this IShardingManager manager,
                                                Type entityType, object?entity, string?tableName)
    {
        var attribute  = ShardedAttribute.ParseFromEntity(entityType, tableName);
        var descriptor = manager.CreateDescriptor(attribute);

        descriptor.ReferenceType  = entityType;
        descriptor.ReferenceValue = entity;
        descriptor.ReferenceName  = tableName;

        descriptor.DefaultStrategy?.FormatSuffix(descriptor);
        descriptor.Entity?.Properties.ForEach(p => p.Strategy.FormatSuffix(descriptor));

        return(descriptor);
    }
예제 #4
0
        public TenantDbManager(
            IShardingManager shardingManager,
            ICatalogRepository catalogRepository,
            IInfrastructureClient infrastructureClient,
            IShardingSQLHelper shardingSQLHelper,
            IKeyVaultClient keyVaultClient,
            IConfiguration configuration)
        {
            ShardingManager      = shardingManager;
            CatalogRepository    = catalogRepository;
            InfrastructureClient = infrastructureClient;
            ShardingSQLHelper    = shardingSQLHelper;
            KeyVaultClient       = keyVaultClient;
            Configuration        = configuration;

            CurrentTenantDatabase = $"{Configuration["TenantConfig:TenantServer"]}.database.windows.net";
        }
    private static ShardedDescriptor CreateDescriptor(this IShardingManager manager,
                                                      ShardedAttribute attribute)
    {
        if (string.IsNullOrEmpty(attribute.BaseName))
        {
            throw new ArgumentException($"The {nameof(attribute)}.{nameof(attribute.BaseName)} is null or empty.");
        }

        var descriptor = new ShardedDescriptor(attribute.BaseName, attribute.Suffix);

        if (attribute.DefaultStrategyType is not null)
        {
            descriptor.DefaultStrategy = manager.GetStrategy(attribute.DefaultStrategyType);
        }

        return(descriptor);
    }
예제 #6
0
    /// <summary>
    /// 通过带分片与复数化实体类型名称映射表名(此方法仅支持关系型数据库,同时要求实体添加 <see cref="ShardedAttribute"/> 特性)。
    /// </summary>
    /// <typeparam name="TEntity">指定的实体类型。</typeparam>
    /// <param name="builder">给定的 <see cref="EntityTypeBuilder{TEntity}"/>。</param>
    /// <param name="shardingManager">给定的 <see cref="IShardingManager"/>。</param>
    /// <param name="accessor">给定的 <see cref="DbContextAccessor"/>。</param>
    /// <param name="schema">给定的架构。</param>
    /// <returns>返回 <see cref="EntityTypeBuilder{TEntity}"/>。</returns>
    public static EntityTypeBuilder <TEntity> ToTableWithSharding <TEntity>(this EntityTypeBuilder <TEntity> builder,
                                                                            IShardingManager shardingManager, DbContextAccessor accessor, string?schema)
        where TEntity : class
    {
        var entity = accessor.Set <TEntity>().FirstBySpecification();

        if (entity is not null)
        {
            var tableName  = builder.Metadata.GetTableName();
            var descriptor = shardingManager.ShardEntity(typeof(TEntity), entity, tableName);

            if (!descriptor.BaseName.Equals(tableName, StringComparison.Ordinal))
            {
                builder.Metadata.SetTableName(descriptor.BaseName);
            }
        }

        builder.Metadata.SetSchema(schema);

        return(builder);
    }
예제 #7
0
 public TenantsService(IShardingManager shardingManager, ITenantContext tenantContext)
 {
     _shardingManager = shardingManager;
     _tenantContext   = tenantContext;
 }
 /// <summary>
 /// 对存取器的数据库分片。
 /// </summary>
 /// <param name="shardingManager">给定的 <see cref="IShardingManager"/>。</param>
 /// <param name="accessor">给定的 <see cref="IAccessor"/>。</param>
 /// <returns>返回 <see cref="IAccessor"/>。</returns>
 public static IAccessor ShardDatabase(this IShardingManager shardingManager, IAccessor accessor)
 => shardingManager.ShardDatabase(accessor, out _);
예제 #9
0
 public TenantDbConnectionStringfactory(IShardingManager shardingManager, IStorePerRequestTenantData storePerRequestTenantData)
 {
     ShardingManager           = shardingManager;
     StorePerRequestTenantData = storePerRequestTenantData;
 }
예제 #10
0
 /// <summary>
 /// 通过带分片与复数化实体类型名称映射表名(此方法仅支持关系型数据库,同时要求实体添加 <see cref="ShardedAttribute"/> 特性)。
 /// </summary>
 /// <typeparam name="TEntity">指定的实体类型。</typeparam>
 /// <param name="builder">给定的 <see cref="EntityTypeBuilder{TEntity}"/>。</param>
 /// <param name="shardingManager">给定的 <see cref="IShardingManager"/>。</param>
 /// <param name="accessor">给定的 <see cref="DbContextAccessor"/>。</param>
 /// <returns>返回 <see cref="EntityTypeBuilder{TEntity}"/>。</returns>
 public static EntityTypeBuilder <TEntity> ToTableWithSharding <TEntity>(this EntityTypeBuilder <TEntity> builder,
                                                                         IShardingManager shardingManager, DbContextAccessor accessor)
     where TEntity : class
 => builder.ToTableWithSharding(shardingManager, accessor, schema : null);