[#161]支持分库迁移

This commit is contained in:
xuejiaming 2022-07-04 22:47:03 +08:00
parent 4cd1a8a073
commit 98f76b409b
21 changed files with 413 additions and 28 deletions

View File

@ -31,7 +31,7 @@ namespace Sample.Migrations.EFCores
var newCmds = builder.GetCommandList().ToList();
var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList();
MigrationHelper.Generate<TShardingDbContext>(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
MigrationHelper.Generate(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
}
}
}

View File

@ -32,7 +32,7 @@ namespace Sample.MySql
{
Id = id.ToString(),
Age = id,
Name = $"name_{id}",
Name = $"ds{(id%3)}",
});
}
var userModMonths = new List<SysUserLogByMonth>();

View File

@ -0,0 +1,32 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;
using Pomelo.EntityFrameworkCore.MySql.Migrations;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Helpers;
namespace Sample.MySql
{
public class ShardingMySqlMigrationsSqlGenerator:MySqlMigrationsSqlGenerator
{
private readonly IShardingRuntimeContext _shardingRuntimeContext;
public ShardingMySqlMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IRelationalAnnotationProvider annotationProvider, IMySqlOptions options,IShardingRuntimeContext shardingRuntimeContext) : base(dependencies, annotationProvider, options)
{
_shardingRuntimeContext = shardingRuntimeContext;
}
protected override void Generate(
MigrationOperation operation,
IModel model,
MigrationCommandListBuilder builder)
{
var oldCmds = builder.GetCommandList().ToList();
base.Generate(operation, model, builder);
var newCmds = builder.GetCommandList().ToList();
var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList();
MigrationHelper.Generate(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
}
}
}

View File

@ -14,7 +14,10 @@ public class SysUserModVirtualDataSourceRoute:AbstractShardingOperatorVirtualDat
public override List<string> GetAllDataSourceNames()
{
return Enumerable.Range(0, 500).Select(o => $"ds{o}").ToList();
return new List<string>()
{
"ds0", "ds1", "ds2"
};
}
public override bool AddDataSourceName(string dataSourceName)

View File

@ -1,17 +1,36 @@
using System.Diagnostics;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Migrations;
using Sample.MySql.DbContexts;
using Sample.MySql.Shardings;
using ShardingCore;
using ShardingCore.Bootstrappers;
using ShardingCore.Core;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.EFCores;
using ShardingCore.Extensions;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.MySql
{
// public class AutoStart : IHostedService
// {
//
// public AutoStart(IShardingBootstrapper shardingBootstrapper)
// {
// shardingBootstrapper.Start();
// }
// public Task StartAsync(CancellationToken cancellationToken)
// {
// return Task.CompletedTask;
// }
//
// public Task StopAsync(CancellationToken cancellationToken)
// {
// return Task.CompletedTask;
// }
// }
public class Startup
{
public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder =>
@ -28,6 +47,7 @@ namespace Sample.MySql
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// services.AddHostedService<AutoStart>();
services.AddControllers();
// services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseMySql(hostBuilderContext.Configuration.GetSection("MySql")["ConnectionString"],new MySqlServerVersion("5.7.15"))
// ,op =>
@ -49,7 +69,7 @@ namespace Sample.MySql
{
o.AddShardingTableRoute<SysUserLogByMonthRoute>();
o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
// o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
}).UseConfig(o =>
{
o.UseShardingQuery((conStr,builder)=>
@ -68,6 +88,19 @@ namespace Sample.MySql
.EnableSensitiveDataLogging();
});
o.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
o.AddExtraDataSource(sp=>new Dictionary<string, string>()
{
{"ds1", "server=127.0.0.1;port=3306;database=dbdbd1;userid=root;password=root;"},
{"ds2", "server=127.0.0.1;port=3306;database=dbdbd2;userid=root;password=root;"}
});
o.UseShellDbContextConfigure(b =>
{
b.ReplaceService<IMigrator, ShardingMigrator>();
});
o.UseExecutorDbContextConfigure(b =>
{
b.ReplaceService<IMigrationsSqlGenerator, ShardingMySqlMigrationsSqlGenerator>();
});
}).ReplaceService<ITableEnsureManager,MySqlTableEnsureManager>(ServiceLifetime.Singleton)
.Build(sp);
stopwatch.Stop();
@ -120,6 +153,17 @@ namespace Sample.MySql
app.UseDeveloperExceptionPage();
}
app.ApplicationServices.UseAutoShardingCreate();
using (var scope = app.ApplicationServices.CreateScope())
{
var defaultShardingDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
if (defaultShardingDbContext.Database.GetPendingMigrations().Any())
{
defaultShardingDbContext.Database.Migrate();
}
}
app.ApplicationServices.UseAutoTryCompensateTable();
app.UseRouting();

View File

@ -59,7 +59,7 @@ namespace Samples.AutoByDate.SqlServer
/// <summary>
/// https://github.com/Coldairarrow/EFCore.Sharding/blob/master/src/EFCore.Sharding.SqlServer/ShardingSqlServerMigrationsSqlGenerator.cs
/// </summary>
public class ShardingSqlServerMigrationsSqlGenerator<TShardingDbContext> : SqlServerMigrationsSqlGenerator where TShardingDbContext : DbContext, IShardingDbContext
public class ShardingSqlServerMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
{
private readonly IShardingRuntimeContext _shardingRuntimeContext;
@ -78,7 +78,7 @@ namespace Samples.AutoByDate.SqlServer
var newCmds = builder.GetCommandList().ToList();
var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList();
MigrationHelper.Generate<TShardingDbContext>(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
MigrationHelper.Generate(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
}
}
}

View File

@ -24,7 +24,7 @@ namespace ShardingCore.Core.RuntimeContexts
public interface IShardingRuntimeContext
{
IShardingProvider GetIhardingProvider();
IShardingProvider GetShardingProvider();
IShardingComparer GetShardingComparer();
IShardingCompilerExecutor GetShardingCompilerExecutor();
IShardingReadWriteManager GetShardingReadWriteManager();

View File

@ -66,7 +66,7 @@ namespace ShardingCore.Core.RuntimeContexts
}
private IShardingProvider _shardingProvider;
public IShardingProvider GetIhardingProvider()
public IShardingProvider GetShardingProvider()
{
return _shardingProvider??=GetRequiredService<IShardingProvider>();
}
@ -187,7 +187,7 @@ namespace ShardingCore.Core.RuntimeContexts
try
{
var shardingProvider = GetIhardingProvider();
var shardingProvider = GetShardingProvider();
using (var scope = shardingProvider.CreateScope())
{
using (var dbContext = _dbContextCreator.GetShellDbContext(scope.ServiceProvider))
@ -222,6 +222,11 @@ namespace ShardingCore.Core.RuntimeContexts
foreach (var entityType in entityTypes)
{
trackerManager.AddDbContextModel(entityType.ClrType, entityType.FindPrimaryKey() != null);
if (!entityMetadataManager.IsSharding(entityType.ClrType))
{
var entityMetadata = new EntityMetadata(entityType.ClrType);
entityMetadataManager.AddEntityMetadata(entityMetadata);
}
entityMetadataManager.TryInitModel(entityType);
}
}
@ -289,7 +294,7 @@ namespace ShardingCore.Core.RuntimeContexts
private void InitFieldValue()
{
GetIhardingProvider();
GetShardingProvider();
GetShardingComparer();
GetShardingCompilerExecutor();
GetShardingReadWriteManager();

View File

@ -0,0 +1,8 @@
namespace ShardingCore.Core.ShardingMigrations.Abstractions
{
public interface IShardingMigrationAccessor
{
ShardingMigrationContext ShardingMigrationContext { get; set; }
}
}

View File

@ -0,0 +1,13 @@
namespace ShardingCore.Core.ShardingMigrations.Abstractions
{
public interface IShardingMigrationManager
{
ShardingMigrationContext Current { get; }
/// <summary>
/// 创建路由scope
/// </summary>
/// <returns></returns>
ShardingMigrationScope CreateScope();
}
}

View File

@ -0,0 +1,17 @@
using System.Threading;
using ShardingCore.Core.ShardingMigrations.Abstractions;
namespace ShardingCore.Core.ShardingMigrations
{
public class ShardingMigrationAccessor:IShardingMigrationAccessor
{
private static AsyncLocal<ShardingMigrationContext> _shardingMigrationContext = new AsyncLocal<ShardingMigrationContext>();
public ShardingMigrationContext ShardingMigrationContext
{
get => _shardingMigrationContext.Value;
set => _shardingMigrationContext.Value = value;
}
}
}

View File

@ -0,0 +1,16 @@
namespace ShardingCore.Core.ShardingMigrations
{
public class ShardingMigrationContext
{
/// <summary>
/// 当前的数据源名称
/// </summary>
public string CurrentDataSourceName { get; set; }
public static ShardingMigrationContext Create()
{
return new ShardingMigrationContext();
}
}
}

View File

@ -0,0 +1,22 @@
using ShardingCore.Core.ShardingMigrations.Abstractions;
namespace ShardingCore.Core.ShardingMigrations
{
public class ShardingMigrationManager:IShardingMigrationManager
{
private readonly IShardingMigrationAccessor _shardingMigrationAccessor;
public ShardingMigrationManager(IShardingMigrationAccessor shardingMigrationAccessor)
{
_shardingMigrationAccessor = shardingMigrationAccessor;
}
public ShardingMigrationContext Current => _shardingMigrationAccessor.ShardingMigrationContext;
public ShardingMigrationScope CreateScope()
{
var shardingMigrationScope = new ShardingMigrationScope(_shardingMigrationAccessor);
_shardingMigrationAccessor.ShardingMigrationContext = ShardingMigrationContext.Create();
return shardingMigrationScope;
}
}
}

View File

@ -0,0 +1,8 @@
using System;
namespace ShardingCore.Core.ShardingMigrations
{
public class ShardingMigrationOptions
{
}
}

View File

@ -0,0 +1,20 @@
using System;
using ShardingCore.Core.ShardingMigrations.Abstractions;
namespace ShardingCore.Core.ShardingMigrations
{
public class ShardingMigrationScope:IDisposable
{
private readonly IShardingMigrationAccessor _shardingMigrationAccessor;
public ShardingMigrationScope(IShardingMigrationAccessor shardingMigrationAccessor)
{
_shardingMigrationAccessor = shardingMigrationAccessor;
}
public void Dispose()
{
_shardingMigrationAccessor.ShardingMigrationContext = null;
}
}
}

View File

@ -124,7 +124,7 @@ namespace ShardingCore.DynamicDataSources
}
else
{
dbContext.RemoveDbContextAllRelationModelThatIsNoSharding();
dbContext.RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly();
}
dbContext.Database.EnsureCreated();

View File

@ -0,0 +1,65 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.ShardingMigrations.Abstractions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.EFCores
{
public class ShardingMigrator:Migrator
{
private readonly IShardingRuntimeContext _shardingRuntimeContext;
public ShardingMigrator(IShardingRuntimeContext shardingRuntimeContext,IMigrationsAssembly migrationsAssembly, IHistoryRepository historyRepository, IDatabaseCreator databaseCreator, IMigrationsSqlGenerator migrationsSqlGenerator, IRawSqlCommandBuilder rawSqlCommandBuilder, IMigrationCommandExecutor migrationCommandExecutor, IRelationalConnection connection, ISqlGenerationHelper sqlGenerationHelper, ICurrentDbContext currentContext, IModelRuntimeInitializer modelRuntimeInitializer, IDiagnosticsLogger<DbLoggerCategory.Migrations> logger, IRelationalCommandDiagnosticsLogger commandLogger, IDatabaseProvider databaseProvider) : base(migrationsAssembly, historyRepository, databaseCreator, migrationsSqlGenerator, rawSqlCommandBuilder, migrationCommandExecutor, connection, sqlGenerationHelper, currentContext, modelRuntimeInitializer, logger, commandLogger, databaseProvider)
{
_shardingRuntimeContext = shardingRuntimeContext;
}
public override void Migrate(string targetMigration = null)
{
this.MigrateAsync(targetMigration).WaitAndUnwrapException();
// base.Migrate(targetMigration);
}
public override async Task MigrateAsync(string targetMigration = null, CancellationToken cancellationToken = new CancellationToken())
{
var virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
var shardingProvider = _shardingRuntimeContext.GetShardingProvider();
var dbContextCreator = _shardingRuntimeContext.GetDbContextCreator();
var routeTailFactory = _shardingRuntimeContext.GetRouteTailFactory();
var shardingMigrationManager = _shardingRuntimeContext.GetRequiredService<IShardingMigrationManager>();
var allDataSourceNames = virtualDataSource.GetAllDataSourceNames();
using (var scope=shardingProvider.CreateScope())
{
using (var shellDbContext = dbContextCreator.GetShellDbContext(scope.ServiceProvider))
{
var shardingDbContext = (IShardingDbContext)shellDbContext;
foreach (var dataSourceName in allDataSourceNames)
{
using (shardingMigrationManager.CreateScope())
{
shardingMigrationManager.Current.CurrentDataSourceName = dataSourceName;
using (var dbContext = shardingDbContext.GetDbContext(dataSourceName, true,
routeTailFactory.Create(string.Empty, false)))
{
if ((await dbContext.Database.GetPendingMigrationsAsync()).Any())
{
await dbContext.Database.MigrateAsync();
}
}
}
}
}
}
}
}
}

View File

@ -103,10 +103,10 @@ namespace ShardingCore.Extensions
//#endif
// }
/// <summary>
/// 移除所有的没有分片的表
/// 移除所有除了仅分库的
/// </summary>
/// <param name="dbContext"></param>
public static void RemoveDbContextAllRelationModelThatIsNoSharding(this DbContext dbContext)
public static void RemoveDbContextAllRelationModelWithoutShardingDataSourceOnly(this DbContext dbContext)
{
#if !EFCORE2&&!EFCORE3&&!EFCORE5&&!EFCORE6
throw new NotImplementedException();

View File

@ -12,6 +12,8 @@ using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore.Core;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.ShardingMigrations.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
@ -31,18 +33,22 @@ namespace ShardingCore.Helpers
public class MigrationHelper
{
private MigrationHelper() { }
public static void Generate<TShardingDContext>(
public static void Generate(
IShardingRuntimeContext shardingRuntimeContext,
MigrationOperation operation,
MigrationCommandListBuilder builder,
ISqlGenerationHelper sqlGenerationHelper,
List<MigrationCommand> addCmds
) where TShardingDContext:DbContext,IShardingDbContext
)
{
var migrationCommands = (List<MigrationCommand>) builder.GetFieldValue("_commands");
var shardingMigrationManager = shardingRuntimeContext.GetRequiredService<IShardingMigrationManager>();
var virtualDataSource = shardingRuntimeContext.GetRequiredService<IVirtualDataSource>();
if (shardingMigrationManager.Current == null||shardingMigrationManager.Current.CurrentDataSourceName==virtualDataSource.DefaultDataSourceName)
{
addCmds.ForEach(aAddCmd =>
{
var shardingCmds = BuildShardingCmds<TShardingDContext>(shardingRuntimeContext,operation, aAddCmd.CommandText, sqlGenerationHelper);
var shardingCmds = BuildShardingCmds(shardingRuntimeContext,operation, aAddCmd.CommandText, sqlGenerationHelper);
if (shardingCmds.IsNotEmpty())
{
migrationCommands.Remove(aAddCmd);
@ -55,9 +61,33 @@ namespace ShardingCore.Helpers
}
});
}
else
{
addCmds.ForEach(aAddCmd =>
{
var (migrationResult,shardingCmds) = BuildDataSourceShardingCmds(shardingRuntimeContext,shardingMigrationManager.Current.CurrentDataSourceName,operation, aAddCmd.CommandText, sqlGenerationHelper);
//如果是分库的
if (migrationResult==MigrationResultEnum.DataSourceTableCommand)
{
if (shardingCmds.IsNotEmpty())
{
migrationCommands.Remove(aAddCmd);
//针对builder的原始表进行移除
shardingCmds.ForEach(aShardingCmd =>
{
builder.Append(aShardingCmd)
.EndCommand();
});
}
}else if (migrationResult==MigrationResultEnum.TableCommand)//如果不是分库并且有表的话那么就把命令删除掉
{
migrationCommands.Remove(aAddCmd);
}
});
}
}
private static List<string> BuildShardingCmds<TShardingDContext>(IShardingRuntimeContext shardingRuntimeContext,MigrationOperation operation, string sourceCmd, ISqlGenerationHelper sqlGenerationHelper)
where TShardingDContext : DbContext, IShardingDbContext
private static List<string> BuildShardingCmds(IShardingRuntimeContext shardingRuntimeContext,MigrationOperation operation, string sourceCmd, ISqlGenerationHelper sqlGenerationHelper)
{
//所有MigrationOperation定义
//https://github.com/dotnet/efcore/tree/b970bf29a46521f40862a01db9e276e6448d3cb0/src/EFCore.Relational/Migrations/Operations
@ -114,6 +144,92 @@ namespace ShardingCore.Helpers
return string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName);
}
}
private static (MigrationResultEnum migrationResult,List<string>) BuildDataSourceShardingCmds(IShardingRuntimeContext shardingRuntimeContext,string dataSourceName,MigrationOperation operation, string sourceCmd, ISqlGenerationHelper sqlGenerationHelper)
{
//所有MigrationOperation定义
//https://github.com/dotnet/efcore/tree/b970bf29a46521f40862a01db9e276e6448d3cb0/src/EFCore.Relational/Migrations/Operations
//ColumnOperation仅替换Table
//其余其余都是将Name和Table使用分表名替换
var dataSourceRouteManager = shardingRuntimeContext.GetDataSourceRouteManager();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
var tableRouteManager = shardingRuntimeContext.GetTableRouteManager();
var tableRoutes = tableRouteManager.GetRoutes();
var existsShardingTables = tableRoutes.ToDictionary(o => o.EntityMetadata.LogicTableName, o => o.GetTails().Select(p=>$"{o.EntityMetadata.LogicTableName}{o.EntityMetadata.TableSeparator}{p}").ToList());
//Dictionary<string, List<string>> _existsShardingTables
// = Cache.ServiceProvider.GetService<ShardingContainer>().ExistsShardingTables;
List<string> resList = new List<string>();
string absTableName = string.Empty;
string name = operation.GetPropertyValue("Name") as string;
string tableName = operation.GetPropertyValue("Table") as string;
string pattern = string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName);
Func<KeyValuePair<string, List<string>>, bool> where = x =>
existsShardingTables.Any(y =>x.Key==y.Key&& Regex.IsMatch(name, BuildPattern(y.Key)));
if (!string.IsNullOrWhiteSpace(tableName))
{
absTableName = tableName;
}
else if (!string.IsNullOrWhiteSpace(name))
{
if (existsShardingTables.Any(x => where(x)))
{
absTableName = existsShardingTables.Where(x => where(x)).FirstOrDefault().Key;
}
else
{
absTableName = name;
}
}
MigrationResultEnum migrationResult = MigrationResultEnum.OtherCommand;
var entityMetadata = entityMetadataManager.TryGetByLogicTableName(absTableName);
if (entityMetadata != null)
{
migrationResult = MigrationResultEnum.TableCommand;
bool isShardingDataSource =entityMetadata.IsShardingDataSource();
if (isShardingDataSource)
{
var virtualDataSourceRoute = dataSourceRouteManager.GetRoute(entityMetadata.EntityType);
isShardingDataSource = virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName);
}
if (isShardingDataSource)
{
migrationResult= MigrationResultEnum.DataSourceTableCommand;
}
//分表
if (!string.IsNullOrWhiteSpace(absTableName) && existsShardingTables.ContainsKey(absTableName))
{
var shardings = existsShardingTables[absTableName];
shardings.ForEach(aShardingTable =>
{
string newCmd = sourceCmd;
GetReplaceGroups(operation, absTableName, aShardingTable).ForEach(aReplace =>
{
newCmd = newCmd.Replace(
sqlGenerationHelper.DelimitIdentifier(aReplace.sourceName),
sqlGenerationHelper.DelimitIdentifier(aReplace.targetName));
});
if (newCmd.Contains("EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE'"))
{
newCmd=newCmd.Replace($"EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'{absTableName}'", $"EXEC sp_addextendedproperty 'MS_Description', @description, 'SCHEMA', @defaultSchema, 'TABLE', N'{aShardingTable}'");
}
resList.Add(newCmd);
});
}
}
return (migrationResult,resList);
string BuildPattern(string absTableName)
{
return string.Format("^({0})$|^({0}_.*?)$|^(.*?_{0}_.*?)$|^(.*?_{0})$", absTableName);
}
}
private static List<(string sourceName, string targetName)> GetReplaceGroups(
MigrationOperation operation, string sourceTableName, string targetTableName)
{

View File

@ -0,0 +1,9 @@
namespace ShardingCore.Helpers
{
public enum MigrationResultEnum
{
OtherCommand,
DataSourceTableCommand,
TableCommand
}
}

View File

@ -29,6 +29,8 @@ using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.QueryTrackers;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.ShardingConfigurations.ConfigBuilders;
using ShardingCore.Core.ShardingMigrations;
using ShardingCore.Core.ShardingMigrations.Abstractions;
using ShardingCore.Core.UnionAllMergeShardingProviders;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
@ -144,6 +146,10 @@ namespace ShardingCore
services.TryAddSingleton<IQueryableRewriteEngine, QueryableRewriteEngine>();
services.TryAddSingleton<IQueryableOptimizeEngine, QueryableOptimizeEngine>();
//migration manage
services.TryAddSingleton<IShardingMigrationAccessor, ShardingMigrationAccessor>();
services.TryAddSingleton<IShardingMigrationManager, ShardingMigrationManager>();
//route manage
services.TryAddSingleton<IShardingRouteManager, ShardingRouteManager>();
services.TryAddSingleton<IShardingRouteAccessor, ShardingRouteAccessor>();
@ -151,6 +157,7 @@ namespace ShardingCore
//sharding page
services.TryAddSingleton<IShardingPageManager, ShardingPageManager>();
services.TryAddSingleton<IShardingPageAccessor, ShardingPageAccessor>();
services.TryAddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
services.TryAddSingleton<IUnionAllMergeManager, UnionAllMergeManager>();
services.TryAddSingleton<IUnionAllMergeAccessor, UnionAllMergeAccessor>();