修复大部分代码和优化添加,独立使用datasourceroutemanager

This commit is contained in:
xuejiaming 2022-07-03 16:52:03 +08:00
parent 2d4b9b0779
commit d18ba69dfc
76 changed files with 854 additions and 595 deletions

View File

@ -61,7 +61,7 @@ namespace Sample.AutoCreateIfPresent
/// 仅启动时调用
/// </summary>
/// <returns></returns>
public override List<string> GetAllTails()
public override List<string> GetTails()
{
//启动寻找有哪些表后缀
using (var connection = new MySqlConnection(_virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultConnectionString))

View File

@ -3,6 +3,7 @@ using Sample.AutoCreateIfPresent;
using ShardingCore;
using ShardingCore.Bootstrappers;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
ILoggerFactory efLogger = LoggerFactory.Create(builder =>
{
@ -21,14 +22,11 @@ builder.Services.AddShardingDbContext<DefaultDbContext>()
.AddEntityConfig(o =>
{
o.ThrowIfQueryRouteNotMatch = false;
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AddShardingTableRoute<OrderByHourRoute>();
o.AddShardingTableRoute<AreaDeviceRoute>();
})
.AddConfig(o =>
{
o.ConfigId = "c1";
o.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=shardingTest;userid=root;password=root;");
o.UseShardingQuery((conn, b) =>
{
@ -38,8 +36,7 @@ builder.Services.AddShardingDbContext<DefaultDbContext>()
{
b.UseMySql(conn, new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger);
});
o.ReplaceTableEnsureManager(sp=>new MySqlTableEnsureManager<DefaultDbContext>());
}).EnsureConfig();
}).ReplaceService<ITableEnsureManager,MySqlTableEnsureManager>().EnsureConfig();
var app = builder.Build();
// Configure the HTTP request pipeline.
@ -48,7 +45,8 @@ if (app.Environment.IsDevelopment())
// app.UseSwagger();
// app.UseSwaggerUI();
}
app.Services.GetRequiredService<IShardingBootstrapper>().Start();
app.Services.UseAutoShardingCreate();
app.Services.UseAutoTryCompensateTable();

View File

@ -15,7 +15,6 @@ namespace Sample.BulkConsole.Entities
public string Id { get; set; }
public string OrderNo { get; set; }
public int Seq { get; set; }
[ShardingTableKey]
public DateTime CreateTime { get; set; }
}
}

View File

@ -31,7 +31,7 @@ namespace Sample.BulkConsole
public override void Configure(EntityMetadataTableBuilder<Order> builder)
{
builder.ShardingProperty(o => o.CreateTime);
}
public override bool AutoCreateTableByTime()

View File

@ -13,6 +13,7 @@ using System.Linq;
using ShardingCore.Bootstrappers;
using ShardingCore.Extensions.ShardingPageExtensions;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.BulkConsole
{
@ -30,13 +31,10 @@ namespace Sample.BulkConsole
services.AddShardingDbContext<MyShardingDbContext>()
.AddEntityConfig(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AddShardingTableRoute<OrderVirtualRoute>();
})
.AddConfig(op =>
{
op.ConfigId = "c1";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
@ -45,12 +43,12 @@ namespace Sample.BulkConsole
{
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MyShardingDbContext>());
op.AddDefaultDataSource("ds0", "Data Source=localhost;Initial Catalog=MyOrderSharding;Integrated Security=True;");
}).EnsureConfig();
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().EnsureConfig();
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetService<IShardingBootstrapper>().Start();
serviceProvider.UseAutoShardingCreate();
serviceProvider.UseAutoTryCompensateTable();
using (var serviceScope = serviceProvider.CreateScope())
{
var myShardingDbContext = serviceScope.ServiceProvider.GetService<MyShardingDbContext>();

View File

@ -10,26 +10,24 @@ using Sample.Migrations.EFCores;
using ShardingCore;
using ShardingCore.Bootstrappers;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.Migrations
{
public class DefaultDesignTimeDbContextFactory: IDesignTimeDbContextFactory<DefaultShardingTableDbContext>
{
{
private static IServiceProvider _serviceProvider;
static DefaultDesignTimeDbContextFactory()
{
var services = new ServiceCollection();
services.AddShardingDbContext<DefaultShardingTableDbContext>()
.AddEntityConfig(o =>
{
o.CreateShardingTableOnStart = false;
o.CreateDataBaseOnlyOnStart = true;
o.EnsureCreatedWithOutShardingTable = false;
o.AddShardingTableRoute<ShardingWithModVirtualTableRoute>();
o.AddShardingTableRoute<ShardingWithDateTimeVirtualTableRoute>();
})
.AddConfig(op =>
{
op.ConfigId = "c1";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr)
@ -40,19 +38,15 @@ namespace Sample.Migrations
{
builder.UseSqlServer(connection);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<DefaultShardingTableDbContext>());
op.AddDefaultDataSource("ds0", "Data Source=localhost;Initial Catalog=ShardingCoreDBMigration;Integrated Security=True;");
}).EnsureConfig();
services.AddLogging();
var buildServiceProvider = services.BuildServiceProvider();
ShardingContainer.SetServices(buildServiceProvider);
ShardingContainer.GetService<IShardingBootstrapper>().Start();
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().EnsureConfig();
_serviceProvider = services.BuildServiceProvider();
}
public DefaultShardingTableDbContext CreateDbContext(string[] args)
{
return ShardingContainer.GetService<DefaultShardingTableDbContext>();
return _serviceProvider.GetService<DefaultShardingTableDbContext>();
}
}
}

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Helpers;
using ShardingCore.Sharding.Abstractions;
@ -14,8 +15,11 @@ namespace Sample.Migrations.EFCores
/// </summary>
public class ShardingSqlServerMigrationsSqlGenerator<TShardingDbContext> : SqlServerMigrationsSqlGenerator where TShardingDbContext:DbContext,IShardingDbContext
{
public ShardingSqlServerMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IRelationalAnnotationProvider migrationsAnnotations) : base(dependencies, migrationsAnnotations)
private readonly IShardingRuntimeContext _shardingRuntimeContext;
public ShardingSqlServerMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IRelationalAnnotationProvider migrationsAnnotations,IShardingRuntimeContext shardingRuntimeContext) : base(dependencies, migrationsAnnotations)
{
_shardingRuntimeContext = shardingRuntimeContext;
}
protected override void Generate(
MigrationOperation operation,
@ -27,7 +31,7 @@ namespace Sample.Migrations.EFCores
var newCmds = builder.GetCommandList().ToList();
var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList();
MigrationHelper.Generate<TShardingDbContext>(operation, builder, Dependencies.SqlGenerationHelper, addCmds);
MigrationHelper.Generate<TShardingDbContext>(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
}
}
}

View File

@ -4,6 +4,7 @@ using ShardingCore;
using ShardingCore.Bootstrappers;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
ILoggerFactory efLogger = LoggerFactory.Create(builder =>
{
@ -21,12 +22,9 @@ builder.Services.AddControllers();
builder.Services.AddShardingDbContext<DefaultDbContext>()
.AddEntityConfig(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
})
.AddConfig(op =>
{
op.ConfigId = "c1";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
@ -35,7 +33,6 @@ builder.Services.AddShardingDbContext<DefaultDbContext>()
{
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<DefaultDbContext>());
op.AddDefaultDataSource("ds0", "Data Source=localhost;Initial Catalog=dbmulti;Integrated Security=True;");
op.AddReadWriteSeparation(sp =>
{
@ -49,11 +46,12 @@ builder.Services.AddShardingDbContext<DefaultDbContext>()
}
};
}, ReadStrategyEnum.Loop, defaultEnable: true);
}).EnsureConfig();
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().EnsureConfig();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.Services.GetRequiredService<IShardingBootstrapper>().Start();
app.Services.UseAutoShardingCreate();
app.Services.UseAutoTryCompensateTable();
app.UseAuthorization();
app.MapControllers();

View File

@ -1,63 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Sample.SqlServer.DbContexts;
using Sample.SqlServer.Domain.Entities;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Extensions;
using ShardingCore.TableCreator;
namespace Sample.SqlServer.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class CreateTableController : ControllerBase
{
private readonly IShardingTableCreator<DefaultShardingDbContext> _tableCreator;
private readonly IVirtualDataSourceManager<DefaultShardingDbContext> _virtualDataSourceManager;
private readonly IVirtualTableManager<DefaultShardingDbContext> _virtualTableManager;
private readonly IEntityMetadataManager<DefaultShardingDbContext> _entityMetadataManager;
public CreateTableController(IShardingTableCreator<DefaultShardingDbContext> tableCreator,
IVirtualDataSourceManager<DefaultShardingDbContext> virtualDataSourceManager,
IVirtualTableManager<DefaultShardingDbContext> virtualTableManager,
IEntityMetadataManager<DefaultShardingDbContext> entityMetadataManager)
{
_tableCreator = tableCreator;
_virtualDataSourceManager = virtualDataSourceManager;
_virtualTableManager = virtualTableManager;
_entityMetadataManager = entityMetadataManager;
}
[HttpGet]
public IActionResult Get()
{
var isShardingTable = _entityMetadataManager.IsShardingTable<SysUserMod>();
if (isShardingTable)
{
#region
var defaultDataSourceName = _virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName;
try
{
_tableCreator.CreateTable<SysUserMod>(defaultDataSourceName, "09");
}
catch (Exception e)
{
Console.WriteLine(e);
}
#endregion
//告诉系统SysUserMod 有一张09的表
var virtualTable = _virtualTableManager.GetVirtualTable<SysUserMod>();
_virtualTableManager.AddPhysicTable(virtualTable,new DefaultPhysicTable(virtualTable, "09"));
}
return BadRequest();
}
}
}
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Threading.Tasks;
// using Microsoft.AspNetCore.Mvc;
// using Sample.SqlServer.DbContexts;
// using Sample.SqlServer.Domain.Entities;
// using ShardingCore.Core.EntityMetadatas;
// using ShardingCore.Core.PhysicTables;
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
// using ShardingCore.Core.VirtualTables;
// using ShardingCore.Extensions;
// using ShardingCore.TableCreator;
//
// namespace Sample.SqlServer.Controllers
// {
// [ApiController]
// [Route("[controller]/[action]")]
// public class CreateTableController : ControllerBase
// {
// private readonly IShardingTableCreator _tableCreator;
// private readonly IVirtualDataSourceManager<DefaultShardingDbContext> _virtualDataSourceManager;
// private readonly IVirtualTableManager<DefaultShardingDbContext> _virtualTableManager;
// private readonly IEntityMetadataManager<DefaultShardingDbContext> _entityMetadataManager;
//
// public CreateTableController(IShardingTableCreator<DefaultShardingDbContext> tableCreator,
// IVirtualDataSourceManager<DefaultShardingDbContext> virtualDataSourceManager,
// IVirtualTableManager<DefaultShardingDbContext> virtualTableManager,
// IEntityMetadataManager<DefaultShardingDbContext> entityMetadataManager)
// {
// _tableCreator = tableCreator;
// _virtualDataSourceManager = virtualDataSourceManager;
// _virtualTableManager = virtualTableManager;
// _entityMetadataManager = entityMetadataManager;
// }
// [HttpGet]
// public IActionResult Get()
// {
// var isShardingTable = _entityMetadataManager.IsShardingTable<SysUserMod>();
// if (isShardingTable)
// {
// #region 完全可以用脚本实现这段代码
// var defaultDataSourceName = _virtualDataSourceManager.GetCurrentVirtualDataSource().DefaultDataSourceName;
// try
// {
// _tableCreator.CreateTable<SysUserMod>(defaultDataSourceName, "09");
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// }
// #endregion
// //告诉系统SysUserMod 有一张09的表
// var virtualTable = _virtualTableManager.GetVirtualTable<SysUserMod>();
// _virtualTableManager.AddPhysicTable(virtualTable,new DefaultPhysicTable(virtualTable, "09"));
// }
//
// return BadRequest();
// }
// }
// }

View File

@ -15,6 +15,7 @@ using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Extensions.ShardingQueryableExtensions;
using ShardingCore.Core;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Extensions.ShardingPageExtensions;
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
namespace Sample.SqlServer.Controllers
@ -350,11 +351,11 @@ namespace Sample.SqlServer.Controllers
[HttpGet]
public async Task<IActionResult> Get5(string readNodeName)
{
using (_readWriteManager.CreateScope<DefaultShardingDbContext>())
using (_readWriteManager.CreateScope())
{
_readWriteManager.GetCurrent<DefaultShardingDbContext>().SetReadWriteSeparation(100,true);
_readWriteManager.GetCurrent().SetReadWriteSeparation(100,true);
_readWriteManager.GetCurrent<DefaultShardingDbContext>().AddDataSourceReadNode("A", readNodeName);
_readWriteManager.GetCurrent().AddDataSourceReadNode("A", readNodeName);
var xxxaaa = await _defaultTableDbContext.Set<SysUserSalary>().FirstOrDefaultAsync();
}

View File

@ -20,7 +20,6 @@ namespace Sample.SqlServer.Domain.Entities
/// <summary>
/// 用户Id用于分表
/// </summary>
[ShardingTableKey(TableSeparator = "_")]
public string Id { get; set; }
/// <summary>
/// 用户名称

View File

@ -15,7 +15,6 @@ namespace Sample.SqlServer.Domain.Entities
/// <summary>
/// 每月的金额
/// </summary>
[ShardingTableKey]
public int DateOfMonth { get; set; }
/// <summary>
/// 工资

View File

@ -33,6 +33,7 @@ namespace Sample.SqlServer.Shardings
public override void Configure(EntityMetadataTableBuilder<SysUserMod> builder)
{
builder.ShardingProperty(o => o.Id);
}
}
}

View File

@ -26,7 +26,7 @@ namespace Sample.SqlServer.Shardings
}
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = new DateTime(2020, 1, 1);
var endTime = new DateTime(2021, 12, 1);
@ -43,7 +43,7 @@ namespace Sample.SqlServer.Shardings
public override void Configure(EntityMetadataTableBuilder<SysUserSalary> builder)
{
builder.ShardingProperty(o => o.DateOfMonth);
}
protected string TimeFormatToTail(int time)

View File

@ -20,14 +20,14 @@ namespace Sample.SqlServer.Shardings
}
//数据库已经存在的tail
public override List<string> GetAllTails()
public override List<string> GetTails()
{
return new List<string>() {"", "1"};
}
public override void Configure(EntityMetadataTableBuilder<SysUserMod> builder)
{
builder.ShardingProperty(o => o.Id);
}
public override Func<string, bool> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)

View File

@ -123,7 +123,8 @@ namespace Sample.SqlServer
{
app.UseDeveloperExceptionPage();
}
app.ApplicationServices.UseAutoShardingCreate();
app.ApplicationServices.UseAutoTryCompensateTable();
app.UseRouting();

View File

@ -8,7 +8,9 @@ using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
using ShardingCore.Exceptions;
using ShardingCore.Sharding.Abstractions;
namespace Sample.SqlServer.UnionAllMerge
@ -16,13 +18,17 @@ namespace Sample.SqlServer.UnionAllMerge
public class UnionAllMergeQueryCompiler : QueryCompiler, IUnionAllMergeQueryCompiler
{
private readonly IQueryContextFactory _queryContextFactory;
private readonly IShardingRuntimeContext _shardingRuntimeContext;
private readonly IDatabase _database;
private readonly IDiagnosticsLogger<DbLoggerCategory.Query> _logger;
private readonly IModel _model;
private readonly IUnionAllMergeManager _unionAllMergeManager;
public UnionAllMergeQueryCompiler(IQueryContextFactory queryContextFactory, ICompiledQueryCache compiledQueryCache, ICompiledQueryCacheKeyGenerator compiledQueryCacheKeyGenerator, IDatabase database, IDiagnosticsLogger<DbLoggerCategory.Query> logger, ICurrentDbContext currentContext, IEvaluatableExpressionFilter evaluatableExpressionFilter, IModel model) : base(queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, currentContext, evaluatableExpressionFilter, model)
public UnionAllMergeQueryCompiler(IQueryContextFactory queryContextFactory,IShardingRuntimeContext shardingRuntimeContext, ICompiledQueryCache compiledQueryCache, ICompiledQueryCacheKeyGenerator compiledQueryCacheKeyGenerator, IDatabase database, IDiagnosticsLogger<DbLoggerCategory.Query> logger, ICurrentDbContext currentContext, IEvaluatableExpressionFilter evaluatableExpressionFilter, IModel model) : base(queryContextFactory, compiledQueryCache, compiledQueryCacheKeyGenerator, database, logger, currentContext, evaluatableExpressionFilter, model)
{
_queryContextFactory = queryContextFactory;
_shardingRuntimeContext = shardingRuntimeContext;
_unionAllMergeManager=_shardingRuntimeContext.GetRequiredService<IUnionAllMergeManager>();
_database = database;
_logger = logger;
_model = model;
@ -30,8 +36,7 @@ namespace Sample.SqlServer.UnionAllMerge
public override TResult Execute<TResult>(Expression query)
{
var notSupportManager = ShardingContainer.GetService<IUnionAllMergeManager>();
if (notSupportManager?.Current != null)
if (_unionAllMergeManager?.Current != null)
{
return NotSupportShardingExecute<TResult>(query);
}
@ -58,8 +63,7 @@ namespace Sample.SqlServer.UnionAllMerge
public override TResult ExecuteAsync<TResult>(Expression query, CancellationToken cancellationToken = new CancellationToken())
{
var notSupportManager = ShardingContainer.GetService<IUnionAllMergeManager>();
if (notSupportManager?.Current != null)
if (_unionAllMergeManager?.Current != null)
{
var result = NotSupportShardingExecuteAsync<TResult>(query, cancellationToken);
return result;

View File

@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
@ -16,21 +16,31 @@ namespace Sample.SqlServer.UnionAllMerge
public class UnionAllMergeSqlServerQuerySqlGeneratorFactory<TShardingDbContext> : IQuerySqlGeneratorFactory, IUnionAllMergeQuerySqlGeneratorFactory
where TShardingDbContext : DbContext, IShardingDbContext
{
public UnionAllMergeSqlServerQuerySqlGeneratorFactory(QuerySqlGeneratorDependencies dependencies)
private readonly IShardingRuntimeContext _shardingRuntimeContext;
public UnionAllMergeSqlServerQuerySqlGeneratorFactory(QuerySqlGeneratorDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext)
{
_shardingRuntimeContext = shardingRuntimeContext;
Dependencies = dependencies;
}
public QuerySqlGeneratorDependencies Dependencies { get; }
public QuerySqlGenerator Create() => new UnionAllMergeSqlServerQuerySqlGenerator<TShardingDbContext>(Dependencies);
public QuerySqlGenerator Create() => new UnionAllMergeSqlServerQuerySqlGenerator<TShardingDbContext>(Dependencies,_shardingRuntimeContext);
}
public class UnionAllMergeSqlServerQuerySqlGenerator<TShardingDbContext> : SqlServerQuerySqlGenerator
where TShardingDbContext : DbContext, IShardingDbContext
{
public UnionAllMergeSqlServerQuerySqlGenerator(QuerySqlGeneratorDependencies dependencies)
private readonly IShardingRuntimeContext _shardingRuntimeContext;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IUnionAllMergeManager _unionAllMergeManager;
public UnionAllMergeSqlServerQuerySqlGenerator(QuerySqlGeneratorDependencies dependencies,IShardingRuntimeContext shardingRuntimeContext)
: base(dependencies)
{
_shardingRuntimeContext = shardingRuntimeContext;
_entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
_unionAllMergeManager = shardingRuntimeContext.GetRequiredService<IUnionAllMergeManager>();
}
protected override Expression VisitTable(TableExpression tableExpression)
@ -48,26 +58,24 @@ namespace Sample.SqlServer.UnionAllMerge
private Expression OverrideVisitTable(TableExpression tableExpression)
{
var supportManager = ShardingContainer.GetService<IUnionAllMergeManager>();
if (supportManager?.Current != null)
if (_unionAllMergeManager?.Current != null)
{
var tableRouteResults = supportManager?.Current.TableRoutesResults.ToArray();
if (tableRouteResults.IsNotEmpty() &&
tableRouteResults[0].ReplaceTables.Any(o => o.OriginalName == tableExpression.Name))
var entityMetadata = _entityMetadataManager.TryGetByLogicTableName(tableExpression.Name);
var tableRouteResults = _unionAllMergeManager?.Current.TableRoutesResults.ToArray();
if (tableRouteResults.IsNotEmpty() &&entityMetadata!=null&&
tableRouteResults[0].ReplaceTables.Any(o =>o.EntityType==entityMetadata.EntityType));
{
var tails = tableRouteResults.Select(o => o.ReplaceTables.FirstOrDefault(r => r.OriginalName == tableExpression.Name).Tail).ToHashSet();
var tails = tableRouteResults.Select(o => o.ReplaceTables.FirstOrDefault(r => r.EntityType==entityMetadata.EntityType)?.Tail).ToHashSet();
var sqlGenerationHelper = typeof(QuerySqlGenerator).GetTypeFieldValue(this, "_sqlGenerationHelper") as ISqlGenerationHelper;
var tableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
var virtualTable = tableManager.GetVirtualTable(tableExpression.Name);
string newTableName = null;
if (tails.Count == 1)
{
newTableName = sqlGenerationHelper.DelimitIdentifier($"{tableExpression.Name}{virtualTable.EntityMetadata.TableSeparator}{tails.First()}", tableExpression.Schema);
newTableName = sqlGenerationHelper.DelimitIdentifier($"{tableExpression.Name}{entityMetadata.TableSeparator}{tails.First()}", tableExpression.Schema);
}
else
{
newTableName = "(" + string.Join(" union all ", tails.Select(tail => $"select * from {sqlGenerationHelper.DelimitIdentifier($"{tableExpression.Name}{virtualTable.EntityMetadata.TableSeparator}{tail}", tableExpression.Schema)}")) + ")";
newTableName = "(" + string.Join(" union all ", tails.Select(tail => $"select * from {sqlGenerationHelper.DelimitIdentifier($"{tableExpression.Name}{entityMetadata.TableSeparator}{tail}", tableExpression.Schema)}")) + ")";
}
var relationalCommandBuilder = typeof(QuerySqlGenerator).GetTypeFieldValue(this, "_relationalCommandBuilder") as IRelationalCommandBuilder;

View File

@ -3,11 +3,7 @@ using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Sample.SqlServer3x.Domain.Entities;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Extensions;
using ShardingCore.TableCreator;
@ -24,15 +20,13 @@ namespace Sample.SqlServer3x.Controllers
private readonly ILogger<WeatherForecastController> _logger;
private readonly DefaultDbContext _defaultDbContext;
private readonly IShardingTableCreator<DefaultDbContext> _shardingTableCreator;
private readonly IVirtualTableManager<DefaultDbContext> _virtualTableManager;
private readonly IShardingTableCreator _shardingTableCreator;
public WeatherForecastController(ILogger<WeatherForecastController> logger,DefaultDbContext defaultDbContext, IShardingTableCreator<DefaultDbContext> shardingTableCreator, IVirtualTableManager<DefaultDbContext> virtualTableManager)
public WeatherForecastController(ILogger<WeatherForecastController> logger,DefaultDbContext defaultDbContext, IShardingRuntimeContext shardingRuntimeContext)
{
_logger = logger;
_defaultDbContext = defaultDbContext;
_shardingTableCreator = shardingTableCreator;
_virtualTableManager = virtualTableManager;
_shardingTableCreator = shardingRuntimeContext.GetShardingTableCreator();
}
[HttpGet]
@ -40,32 +34,32 @@ namespace Sample.SqlServer3x.Controllers
{
Console.WriteLine("---------------开始-----------------");
var s = DateTime.Now.ToString("HHmmss");
Task.Run(() =>
{
try
{
var virtualTable = _virtualTableManager.GetVirtualTable(typeof(SysUserMod));
_virtualTableManager.AddPhysicTable(typeof(SysUserMod), new DefaultPhysicTable(virtualTable, s));
_shardingTableCreator.CreateTable<SysUserMod>("A", s);
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
Task.Run(() =>
{
try
{
var virtualTable = _virtualTableManager.GetVirtualTable(typeof(SysUserModAbc));
_virtualTableManager.AddPhysicTable(typeof(SysUserModAbc), new DefaultPhysicTable(virtualTable, s));
_shardingTableCreator.CreateTable<SysUserModAbc>("A", s);
}
catch (Exception e)
{
Console.WriteLine(e);
}
});
// Task.Run(() =>
// {
// try
// {
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(SysUserMod));
// _virtualTableManager.AddPhysicTable(typeof(SysUserMod), new DefaultPhysicTable(virtualTable, s));
// _shardingTableCreator.CreateTable<SysUserMod>("A", s);
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// }
// });
// Task.Run(() =>
// {
// try
// {
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(SysUserModAbc));
// _virtualTableManager.AddPhysicTable(typeof(SysUserModAbc), new DefaultPhysicTable(virtualTable, s));
// _shardingTableCreator.CreateTable<SysUserModAbc>("A", s);
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// }
// });
//try
//{
// var virtualTable = _virtualTableManager.GetVirtualTable(typeof(SysUserMod));

View File

@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.DependencyInjection;
using Sample.SqlServer3x.Domain.Maps;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.ServiceProviders;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions;
@ -27,7 +28,7 @@ namespace Sample.SqlServer3x
}
public class CustomerDbContextCreator : IDbContextCreator<DefaultDbContext>
public class CustomerDbContextCreator : IDbContextCreator
{
public DbContext CreateDbContext(DbContext mainDbContext, ShardingDbContextOptions shardingDbContextOptions)
{
@ -40,6 +41,11 @@ namespace Sample.SqlServer3x
_ = dbContext.Model;
return dbContext;
}
public DbContext GetShellDbContext(IShardingProvider shardingProvider)
{
return shardingProvider.GetService<DefaultDbContext>();
}
}
public class DefaultDbContext : AbstractShardingDbContext, IShardingTableDbContext

View File

@ -17,6 +17,7 @@ using ShardingCore;
using ShardingCore.Bootstrappers;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.SqlServer3x
{
@ -53,16 +54,13 @@ namespace Sample.SqlServer3x
//services.AddDbContext<DefaultDbContext>(op=>op.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreCreate;Integrated Security=True;"));
//services.AddScoped<DbContext,DefaultDbContext>(s=>s.GetService<DefaultDbContext>());
services.AddShardingDbContext<DefaultDbContext>()
.AddEntityConfig(o =>
.UseRouteConfig(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
o.AddShardingTableRoute<SysUserModAbcVirtualTableRoute>();
})
.AddConfig(op =>
.UseConfig(op =>
{
op.ConfigId = "c1";
op.MaxQueryConnectionsLimit = 5;
op.UseShardingQuery((conStr, builder) =>
{
@ -72,14 +70,16 @@ namespace Sample.SqlServer3x
{
builder.UseSqlServer(conn).UseLoggerFactory(efLogger);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<DefaultDbContext>());
op.AddDefaultDataSource("A",
"Data Source=localhost;Initial Catalog=ShardingCoreCreate;Integrated Security=True;"
);
}).EnsureConfig();
})
.ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>(ServiceLifetime.Singleton)
.ReplaceService<IDbContextCreator,CustomerDbContextCreator>(ServiceLifetime.Singleton)
.AddShardingCore();
services.AddScoped<IScopedService, ScopedService>();
services.Replace(
ServiceDescriptor.Singleton<IDbContextCreator<DefaultDbContext>, CustomerDbContextCreator>());
ServiceDescriptor.Singleton<IDbContextCreator, CustomerDbContextCreator>());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -90,8 +90,8 @@ namespace Sample.SqlServer3x
app.UseDeveloperExceptionPage();
}
var shardingBootstrapper = app.ApplicationServices.GetService<IShardingBootstrapper>();
shardingBootstrapper.Start();
app.ApplicationServices.UseAutoShardingCreate();
app.ApplicationServices.UseAutoTryCompensateTable();
app.UseRouting();
app.UseAuthorization();

View File

@ -4,11 +4,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Sample.SqlServerShardingAll.Entities;
using ShardingCore;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.DynamicDataSources;
using ShardingCore.Helpers;
namespace Sample.SqlServerShardingAll.Controllers
{
@ -25,16 +20,16 @@ namespace Sample.SqlServerShardingAll.Controllers
public async Task<IActionResult> Query()
{
#region
var virtualDataSource = ShardingContainer.GetRequiredCurrentVirtualDataSource<MyDbContext>();
var virtualDataSourceRoute1 = virtualDataSource.GetRoute(typeof(Order));
virtualDataSourceRoute1.AddDataSourceName("D");
var virtualDataSourceRoute2 = virtualDataSource.GetRoute(typeof(SysUser));
virtualDataSourceRoute2.AddDataSourceName("D");
DynamicDataSourceHelper.DynamicAppendDataSource<MyDbContext>(virtualDataSource,"D", "连接字符串");
#endregion
// #region 动态数据
//
// var virtualDataSource = ShardingContainer.GetRequiredCurrentVirtualDataSource<MyDbContext>();
//
// var virtualDataSourceRoute1 = virtualDataSource.GetRoute(typeof(Order));
// virtualDataSourceRoute1.AddDataSourceName("D");
// var virtualDataSourceRoute2 = virtualDataSource.GetRoute(typeof(SysUser));
// virtualDataSourceRoute2.AddDataSourceName("D");
// DynamicDataSourceHelper.DynamicAppendDataSource<MyDbContext>(virtualDataSource,"D", "连接字符串");
// #endregion
var sysUser =await _myDbContext.Set<SysUser>().Where(o=>o.Id=="1").FirstOrDefaultAsync();
var sysUserA1 =await _myDbContext.Set<SysUser>().Where(o=>o.Id=="1" && o.Area == "A").FirstOrDefaultAsync();

View File

@ -1,19 +1,16 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Sample.SqlServerShardingAll.VirtualDataSourceRoutes;
using Sample.SqlServerShardingAll.VirtualTableRoutes;
using ShardingCore;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.SqlServerShardingAll
{
@ -37,18 +34,15 @@ namespace Sample.SqlServerShardingAll
services.AddControllers();
services.AddShardingDbContext<MyDbContext>()
.AddEntityConfig(o =>
.UseRouteConfig(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AddShardingDataSourceRoute<OrderVirtualDataSourceRoute>();
o.AddShardingDataSourceRoute<SysUserVirtualDataSourceRoute>();
o.AddShardingTableRoute<SysUserVirtualTableRoute>();
o.AddShardingTableRoute<OrderVirtualTableRoute>();
})
.AddConfig(op =>
.UseConfig(op =>
{
op.ConfigId = "c1";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
@ -57,7 +51,6 @@ namespace Sample.SqlServerShardingAll
{
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MyDbContext>());
op.AddDefaultDataSource("A",
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceTableDBA;Integrated Security=True;");
op.AddExtraDataSource(sp =>
@ -72,7 +65,7 @@ namespace Sample.SqlServerShardingAll
},
};
});
}).EnsureConfig();
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().AddShardingCore();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -83,7 +76,6 @@ namespace Sample.SqlServerShardingAll
app.UseDeveloperExceptionPage();
}
//³õʼ»¯ShardingCore
app.UseShardingCore();
app.UseRouting();

View File

@ -4,6 +4,7 @@ using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Sample.SqlServerShardingAll.Entities;
using ShardingCore;
using ShardingCore.Bootstrappers;
namespace Sample.SqlServerShardingAll
@ -12,7 +13,8 @@ namespace Sample.SqlServerShardingAll
{
public static void UseShardingCore(this IApplicationBuilder app)
{
app.ApplicationServices.GetRequiredService<IShardingBootstrapper>().Start();
app.ApplicationServices.UseAutoShardingCreate();
app.ApplicationServices.UseAutoTryCompensateTable();
}
public static void InitSeed(this IApplicationBuilder app)
{

View File

@ -1,142 +1,142 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Sample.SqlServerShardingDataSource.Entities;
using ShardingCore;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.TableCreator;
namespace Sample.SqlServerShardingDataSource
{
public class DbContextHelper
{
public static void CreateSubDb(string dataSourceName, string connectionString)
{
var _entityMetadataManager = ShardingContainer.GetService<IEntityMetadataManager<MyDbContext>>();
var _virtualDataSource = ShardingContainer.GetRequiredCurrentVirtualDataSource<MyDbContext>();
var _virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<MyDbContext>>();
var _tableCreator = ShardingContainer.GetService<IShardingTableCreator<MyDbContext>>();
using (var serviceScope = ShardingContainer.ServiceProvider.CreateScope())
{
_virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(dataSourceName, connectionString, false));
var virtualDataSourceRoute = _virtualDataSource.GetRoute(typeof(Order));
virtualDataSourceRoute.AddDataSourceName(dataSourceName);
using var context = (DbContext)serviceScope.ServiceProvider.GetService(typeof(MyDbContext));
EnsureCreated(context, dataSourceName);
foreach (var entity in context.Model.GetEntityTypes())
{
var entityType = entity.ClrType;
if (_entityMetadataManager.IsShardingTable(entityType))
{
var virtualTable = _virtualTableManager.GetVirtualTable(entityType);
//创建表
CreateDataTable(dataSourceName, virtualTable);
}
else
{
_tableCreator.CreateTable(dataSourceName, entityType, string.Empty);
}
}
}
}
private static void CreateDataTable(string dataSourceName, IVirtualTable virtualTable)
{
var _tableCreator = ShardingContainer.GetService<IShardingTableCreator<MyDbContext>>();
var entityMetadata = virtualTable.EntityMetadata;
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
{
if (NeedCreateTable(entityMetadata))
{
try
{
//添加物理表
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
_tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, tail);
}
catch (Exception ex)
{
//if (!_shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
//{
// _logger.LogWarning(ex,
// $"table :{virtualTable.GetVirtualTableName()}{entityMetadata.TableSeparator}{tail} will created.");
//}
//TODO: 记录异常日志
System.Diagnostics.Trace.TraceError($"DbContextHelper-->CreateDataTable ERROR: {ex}");
}
}
else
{
//添加物理表
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
}
}
}
private static bool NeedCreateTable(EntityMetadata entityMetadata)
{
if (entityMetadata.AutoCreateTable.HasValue)
{
if (entityMetadata.AutoCreateTable.Value)
return entityMetadata.AutoCreateTable.Value;
else
{
if (entityMetadata.AutoCreateDataSourceTable.HasValue)
return entityMetadata.AutoCreateDataSourceTable.Value;
}
}
if (entityMetadata.AutoCreateDataSourceTable.HasValue)
{
if (entityMetadata.AutoCreateDataSourceTable.Value)
return entityMetadata.AutoCreateDataSourceTable.Value;
else
{
if (entityMetadata.AutoCreateTable.HasValue)
return entityMetadata.AutoCreateTable.Value;
}
}
//return _shardingConfigOption.CreateShardingTableOnStart.GetValueOrDefault();
return true;
}
private static void EnsureCreated(DbContext context, string dataSourceName)
{
var _routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
if (context is IShardingDbContext shardingDbContext)
{
var dbContext = shardingDbContext.GetDbContext(dataSourceName, false, _routeTailFactory.Create(string.Empty));
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
var acquire = System.Threading.Monitor.TryEnter(modelCacheSyncObject, TimeSpan.FromSeconds(3));
if (!acquire)
{
throw new ShardingCoreException("cant get modelCacheSyncObject lock");
}
try
{
dbContext.RemoveDbContextRelationModelThatIsShardingTable();
dbContext.Database.EnsureCreated();
dbContext.RemoveModelCache();
}
finally
{
System.Threading.Monitor.Exit(modelCacheSyncObject);
}
}
}
}
}
// using System;
// using Microsoft.EntityFrameworkCore;
// using Microsoft.Extensions.DependencyInjection;
// using Sample.SqlServerShardingDataSource.Entities;
// using ShardingCore;
// using ShardingCore.Core.EntityMetadatas;
// using ShardingCore.Core.PhysicTables;
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
// using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
// using ShardingCore.Core.VirtualTables;
// using ShardingCore.Exceptions;
// using ShardingCore.Extensions;
// using ShardingCore.Sharding.Abstractions;
// using ShardingCore.TableCreator;
//
// namespace Sample.SqlServerShardingDataSource
// {
// public class DbContextHelper
// {
// public static void CreateSubDb(string dataSourceName, string connectionString)
// {
// var _entityMetadataManager = ShardingContainer.GetService<IEntityMetadataManager<MyDbContext>>();
// var _virtualDataSource = ShardingContainer.GetRequiredCurrentVirtualDataSource<MyDbContext>();
// var _virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<MyDbContext>>();
// var _tableCreator = ShardingContainer.GetService<IShardingTableCreator<MyDbContext>>();
//
// using (var serviceScope = ShardingContainer.ServiceProvider.CreateScope())
// {
// _virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(dataSourceName, connectionString, false));
// var virtualDataSourceRoute = _virtualDataSource.GetRoute(typeof(Order));
// virtualDataSourceRoute.AddDataSourceName(dataSourceName);
//
// using var context = (DbContext)serviceScope.ServiceProvider.GetService(typeof(MyDbContext));
// EnsureCreated(context, dataSourceName);
// foreach (var entity in context.Model.GetEntityTypes())
// {
// var entityType = entity.ClrType;
//
// if (_entityMetadataManager.IsShardingTable(entityType))
// {
// var virtualTable = _virtualTableManager.GetVirtualTable(entityType);
// //创建表
// CreateDataTable(dataSourceName, virtualTable);
// }
// else
// {
// _tableCreator.CreateTable(dataSourceName, entityType, string.Empty);
// }
// }
// }
// }
// private static void CreateDataTable(string dataSourceName, IVirtualTable virtualTable)
// {
// var _tableCreator = ShardingContainer.GetService<IShardingTableCreator<MyDbContext>>();
// var entityMetadata = virtualTable.EntityMetadata;
// foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
// {
// if (NeedCreateTable(entityMetadata))
// {
// try
// {
// //添加物理表
// virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
// _tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, tail);
// }
// catch (Exception ex)
// {
// //if (!_shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
// //{
// // _logger.LogWarning(ex,
// // $"table :{virtualTable.GetVirtualTableName()}{entityMetadata.TableSeparator}{tail} will created.");
// //}
// //TODO: 记录异常日志
// System.Diagnostics.Trace.TraceError($"DbContextHelper-->CreateDataTable ERROR: {ex}");
// }
// }
// else
// {
// //添加物理表
// virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
// }
// }
// }
// private static bool NeedCreateTable(EntityMetadata entityMetadata)
// {
// if (entityMetadata.AutoCreateTable.HasValue)
// {
// if (entityMetadata.AutoCreateTable.Value)
// return entityMetadata.AutoCreateTable.Value;
// else
// {
// if (entityMetadata.AutoCreateDataSourceTable.HasValue)
// return entityMetadata.AutoCreateDataSourceTable.Value;
// }
// }
// if (entityMetadata.AutoCreateDataSourceTable.HasValue)
// {
// if (entityMetadata.AutoCreateDataSourceTable.Value)
// return entityMetadata.AutoCreateDataSourceTable.Value;
// else
// {
// if (entityMetadata.AutoCreateTable.HasValue)
// return entityMetadata.AutoCreateTable.Value;
// }
// }
//
// //return _shardingConfigOption.CreateShardingTableOnStart.GetValueOrDefault();
// return true;
// }
//
// private static void EnsureCreated(DbContext context, string dataSourceName)
// {
// var _routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
//
// if (context is IShardingDbContext shardingDbContext)
// {
// var dbContext = shardingDbContext.GetDbContext(dataSourceName, false, _routeTailFactory.Create(string.Empty));
//
// var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
//
// var acquire = System.Threading.Monitor.TryEnter(modelCacheSyncObject, TimeSpan.FromSeconds(3));
// if (!acquire)
// {
// throw new ShardingCoreException("cant get modelCacheSyncObject lock");
// }
//
// try
// {
// dbContext.RemoveDbContextRelationModelThatIsShardingTable();
// dbContext.Database.EnsureCreated();
// dbContext.RemoveModelCache();
// }
// finally
// {
// System.Threading.Monitor.Exit(modelCacheSyncObject);
// }
// }
// }
// }
// }

View File

@ -12,6 +12,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.SqlServerShardingDataSource
{
@ -35,16 +36,13 @@ namespace Sample.SqlServerShardingDataSource
services.AddControllers();
services.AddShardingDbContext<MyDbContext>()
.AddEntityConfig(o =>
.UseRouteConfig(o =>
{
o.CreateShardingTableOnStart = false;
o.EnsureCreatedWithOutShardingTable = false;
o.AddShardingDataSourceRoute<OrderVirtualDataSourceRoute>();
o.AddShardingDataSourceRoute<SysUserVirtualDataSourceRoute>();
})
.AddConfig(op =>
.UseConfig(op =>
{
op.ConfigId = "c1";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
@ -53,7 +51,6 @@ namespace Sample.SqlServerShardingDataSource
{
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MyDbContext>());
op.AddDefaultDataSource("00",
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceOnly00;Integrated Security=True;");
op.AddExtraDataSource(sp =>
@ -63,7 +60,7 @@ namespace Sample.SqlServerShardingDataSource
o =>
$"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceOnly{o};Integrated Security=True;");
});
}).EnsureConfig();
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().AddShardingCore();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -74,10 +71,7 @@ namespace Sample.SqlServerShardingDataSource
app.UseDeveloperExceptionPage();
}
Stopwatch sp=Stopwatch.StartNew();
app.UseShardingCore();
sp.Stop();
Console.WriteLine("ºÄʱ"+sp.ElapsedMilliseconds);
app.UseRouting();
app.UseAuthorization();

View File

@ -4,6 +4,7 @@ using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Sample.SqlServerShardingDataSource.Entities;
using ShardingCore;
using ShardingCore.Bootstrappers;
namespace Sample.SqlServerShardingDataSource
@ -12,7 +13,8 @@ namespace Sample.SqlServerShardingDataSource
{
public static void UseShardingCore(this IApplicationBuilder app)
{
app.ApplicationServices.GetRequiredService<IShardingBootstrapper>().Start();
app.ApplicationServices.UseAutoShardingCreate();
app.ApplicationServices.UseAutoTryCompensateTable();
}
public static void InitSeed(this IApplicationBuilder app)
{

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Sample.SqlServerShardingTable.Entities;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Extensions;
using ShardingCore.Helpers;
@ -17,12 +18,12 @@ namespace Sample.SqlServerShardingTable.Controllers
public class TestController : ControllerBase
{
private readonly MyDbContext _myDbContext;
private readonly IVirtualDataSourceManager<MyDbContext> _virtualDataSourceManager;
private readonly IShardingRuntimeContext _shardingRuntimeContext;
public TestController(MyDbContext myDbContext,IVirtualDataSourceManager<MyDbContext> virtualDataSourceManager)
public TestController(MyDbContext myDbContext,IShardingRuntimeContext shardingRuntimeContext)
{
_myDbContext = myDbContext;
_virtualDataSourceManager = virtualDataSourceManager;
_shardingRuntimeContext = shardingRuntimeContext;
}
public async Task<IActionResult> Testa()
{
@ -148,7 +149,7 @@ namespace Sample.SqlServerShardingTable.Controllers
public async Task<IActionResult> DynamicReadWrite()
{
DynamicShardingHelper.DynamicAppendReadWriteConnectionString<MyDbContext>("a","ds0", "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB1;Integrated Security=True;");
DynamicShardingHelper.DynamicAppendReadWriteConnectionString<MyDbContext>(_shardingRuntimeContext,"ds0", "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB1;Integrated Security=True;");
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1").FirstOrDefaultAsync();
return Ok(sysUser);

View File

@ -16,6 +16,7 @@ using Sample.SqlServerShardingTable.VirtualRoutes;
using ShardingCore;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.TableExists;
using ShardingCore.TableExists.Abstractions;
namespace Sample.SqlServerShardingTable
{
@ -42,11 +43,11 @@ namespace Sample.SqlServerShardingTable
// builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
// }).Begin(op =>
// {
// //如果您使用code-first建议选择false
// //如果您使用code-first建议选择false
// op.CreateShardingTableOnStart = true;
// //如果您使用code-first建议修改为fsle
// //如果您使用code-first建议修改为fsle
// op.EnsureCreatedWithOutShardingTable = true;
// //当无法获取路由时会返回默认值而不是报错
// //当无法获取路由时会返回默认值而不是报错
// op.ThrowIfQueryRouteNotMatch = true;
// }).AddShardingTransaction((connection, builder) =>
// {
@ -72,18 +73,13 @@ namespace Sample.SqlServerShardingTable
// },ReadStrategyEnum.Loop,defaultEnable:true).End();
services.AddShardingDbContext<MyDbContext>().AddEntityConfig(op =>
{
//如果您使用code-first建议选择false
op.CreateShardingTableOnStart = true;
//如果您使用code-first建议修改为fsle
op.EnsureCreatedWithOutShardingTable = true;
//当无法获取路由时会返回默认值而不是报错
//当无法获取路由时会返回默认值而不是报错
op.ThrowIfQueryRouteNotMatch = false;
op.AddShardingTableRoute<SysUserVirtualTableRoute>();
op.AddShardingTableRoute<OrderVirtualTableRoute>();
op.AddShardingTableRoute<MultiShardingOrderVirtualTableRoute>();
}).AddConfig(op =>
{
op.ConfigId = "a";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
@ -106,8 +102,7 @@ namespace Sample.SqlServerShardingTable
//}
};
}, ReadStrategyEnum.Loop, defaultEnable: true);
op.ReplaceTableEnsureManager(sp=>new SqlServerTableEnsureManager<MyDbContext>());
}).EnsureConfig();
}).ReplaceService<ITableEnsureManager,SqlServerTableEnsureManager>().EnsureConfig();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Sample.SqlServerShardingTable.Common;
using Sample.SqlServerShardingTable.Entities;
using ShardingCore;
using ShardingCore.Bootstrappers;
namespace Sample.SqlServerShardingTable
@ -13,7 +14,8 @@ namespace Sample.SqlServerShardingTable
{
public static void UseShardingCore(this IApplicationBuilder app)
{
app.ApplicationServices.GetRequiredService<IShardingBootstrapper>().Start();
app.ApplicationServices.UseAutoShardingCreate();
app.ApplicationServices.UseAutoTryCompensateTable();
}
public static void InitSeed(this IApplicationBuilder app)
{

View File

@ -35,7 +35,7 @@ namespace Sample.SqlServerShardingTable.VirtualRoutes
throw new ShardingCoreInvalidOperationException($"cant calc hash route hash code:[{stringHashCode}]");
}
public override List<string> GetAllTails()
public override List<string> GetTails()
{
return new List<string>()
{

View File

@ -31,9 +31,7 @@ namespace Samples.AbpSharding
var wrapOptionsExtension = options.FindExtension<ShardingWrapOptionsExtension>();
if (wrapOptionsExtension != null)
{
_shardingDbContextExecutor =
(IShardingDbContextExecutor)Activator.CreateInstance(
typeof(ShardingDbContextExecutor<>).GetGenericType0(this.GetType()), this);
_shardingDbContextExecutor = new ShardingDbContextExecutor(this);
}
}

View File

@ -15,8 +15,8 @@ namespace Samples.AutoByDate.SqlServer
{
public static IApplicationBuilder UseShardingCore(this IApplicationBuilder app)
{
var shardingBootstrapper = app.ApplicationServices.GetRequiredService<IShardingBootstrapper>();
shardingBootstrapper.Start();
app.ApplicationServices.UseAutoShardingCreate();
app.ApplicationServices.UseAutoTryCompensateTable();
return app;
}
}

View File

@ -9,7 +9,6 @@ namespace Samples.AutoByDate.SqlServer.Domain.Entities
public class TestLogByWeek
{
public string Id { get; set; }
[ShardingTableKey]
public DateTime CreateDate { get; set; }
}
}

View File

@ -12,6 +12,7 @@ using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Update;
using Microsoft.EntityFrameworkCore.Update.Internal;
using Samples.AutoByDate.SqlServer.Domain.Entities;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Helpers;
using ShardingCore.Sharding.Abstractions;
@ -60,8 +61,11 @@ namespace Samples.AutoByDate.SqlServer
/// </summary>
public class ShardingSqlServerMigrationsSqlGenerator<TShardingDbContext> : SqlServerMigrationsSqlGenerator where TShardingDbContext : DbContext, IShardingDbContext
{
public ShardingSqlServerMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IRelationalAnnotationProvider migrationsAnnotations) : base(dependencies, migrationsAnnotations)
private readonly IShardingRuntimeContext _shardingRuntimeContext;
public ShardingSqlServerMigrationsSqlGenerator(MigrationsSqlGeneratorDependencies dependencies, IRelationalAnnotationProvider migrationsAnnotations,IShardingRuntimeContext shardingRuntimeContext) : base(dependencies, migrationsAnnotations)
{
_shardingRuntimeContext = shardingRuntimeContext;
}
protected override void Generate(
@ -74,7 +78,7 @@ namespace Samples.AutoByDate.SqlServer
var newCmds = builder.GetCommandList().ToList();
var addCmds = newCmds.Where(x => !oldCmds.Contains(x)).ToList();
MigrationHelper.Generate<TShardingDbContext>(operation, builder, Dependencies.SqlGenerationHelper, addCmds);
MigrationHelper.Generate<TShardingDbContext>(_shardingRuntimeContext,operation, builder, Dependencies.SqlGenerationHelper, addCmds);
}
}
}

View File

@ -23,7 +23,7 @@ namespace Samples.AutoByDate.SqlServer.Shardings
public override void Configure(EntityMetadataTableBuilder<TestLogByWeek> builder)
{
builder.ShardingProperty(o => o.CreateDate);
}
}
}

View File

@ -34,15 +34,12 @@ namespace Samples.AutoByDate.SqlServer
services.AddShardingDbContext<DefaultShardingDbContext>()
.AddEntityConfig(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AddShardingTableRoute<SysUserLogByDayVirtualTableRoute>();
o.AddShardingTableRoute<SysUserLog1ByDayVirtualTableRoute>();
o.AddShardingTableRoute<TestLogWeekVirtualRoute>();
})
.AddConfig(sp =>
{
sp.ConfigId = "c1";
sp.UseShardingQuery((conStr, builder) =>
{
builder.UseSqlServer(conStr);

View File

@ -35,14 +35,14 @@ namespace ShardingCore.Bootstrappers
private readonly Type _shardingEntityType;
private readonly IShardingProvider _shardingProvider;
private readonly IShardingRouteConfigOptions _shardingRouteConfigOptions;
private readonly IVirtualDataSourceRouteManager _virtualDataSourceRouteManager;
private readonly IDataSourceRouteManager _dataSourceRouteManager;
private readonly ITableRouteManager _tableRouteManager;
private readonly IEntityMetadataManager _entityMetadataManager;
public EntityMetadataInitializer(
IShardingProvider shardingProvider,
IShardingRouteConfigOptions shardingRouteConfigOptions,
IVirtualDataSourceRouteManager virtualDataSourceRouteManager,
IDataSourceRouteManager dataSourceRouteManager,
ITableRouteManager tableRouteManager,
IEntityMetadataManager entityMetadataManager
)
@ -50,7 +50,7 @@ namespace ShardingCore.Bootstrappers
_shardingEntityType = typeof(TEntity);
_shardingProvider = shardingProvider;
_shardingRouteConfigOptions = shardingRouteConfigOptions;
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
_dataSourceRouteManager = dataSourceRouteManager;
_tableRouteManager = tableRouteManager;
_entityMetadataManager = entityMetadataManager;
}
@ -81,7 +81,7 @@ namespace ShardingCore.Bootstrappers
{
entityMetadataDataSourceConfiguration.Configure(creatEntityMetadataDataSourceBuilder);
}
_virtualDataSourceRouteManager.AddVirtualDataSourceRoute(dataSourceRoute);
_dataSourceRouteManager.AddDataSourceRoute(dataSourceRoute);
entityMetadata.CheckShardingDataSourceMetadata();
}

View File

@ -65,6 +65,12 @@ namespace ShardingCore.Core.EntityMetadatas
return null;
return entityMetadata;
}
public EntityMetadata TryGetByLogicTableName(string logicTableName)
{
return _caches.Values.FirstOrDefault(o => o.LogicTableName == logicTableName);
}
/// <summary>
/// 是否是分片对象(包括分表或者分库)
/// </summary>

View File

@ -36,7 +36,8 @@ namespace ShardingCore.Core.EntityMetadatas
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
EntityMetadata TryGet(Type entityType);
EntityMetadata? TryGet(Type entityType);
EntityMetadata? TryGetByLogicTableName(string logicTableName);
/// <summary>
/// 是否是分片对象(包括分表或者分库)
/// </summary>

View File

@ -5,6 +5,7 @@ using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Core.QueryTrackers;
using ShardingCore.Core.ServiceProviders;
using ShardingCore.Core.ShardingPage.Abstractions;
using ShardingCore.Core.TrackerManagers;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
@ -23,6 +24,7 @@ namespace ShardingCore.Core.RuntimeContexts
public interface IShardingRuntimeContext
{
IShardingProvider GetIhardingProvider();
IShardingComparer GetShardingComparer();
IShardingCompilerExecutor GetShardingCompilerExecutor();
IShardingReadWriteManager GetShardingReadWriteManager();
@ -33,6 +35,7 @@ namespace ShardingCore.Core.RuntimeContexts
IEntityMetadataManager GetEntityMetadataManager();
// IVirtualDataSourceManager GetVirtualDataSourceManager();
IVirtualDataSource GetVirtualDataSource();
IDataSourceRouteManager GetDataSourceRouteManager();
ITableRouteManager GetTableRouteManager();
IShardingTableCreator GetShardingTableCreator();
IRouteTailFactory GetRouteTailFactory();
@ -41,6 +44,8 @@ namespace ShardingCore.Core.RuntimeContexts
IUnionAllMergeManager GetUnionAllMergeManager();
IShardingPageManager GetShardingPageManager();
IDataSourceInitializer GetDataSourceInitializer();
void CheckRequirement();
void GetOrCreateShardingRuntimeModel(DbContext dbContext);

View File

@ -7,6 +7,7 @@ using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Core.QueryTrackers;
using ShardingCore.Core.ServiceProviders;
using ShardingCore.Core.ShardingPage.Abstractions;
using ShardingCore.Core.TrackerManagers;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
@ -30,6 +31,8 @@ namespace ShardingCore.Core.RuntimeContexts
private object INIT_LOCK = new object();
private bool isInitModeled = false;
private object INIT_MODEL = new object();
private bool isCheckRequirement = false;
private object CHECK_REQUIREMENT = new object();
private IServiceCollection _serviceMap = new ServiceCollection();
private IServiceProvider _serviceProvider;
@ -62,6 +65,12 @@ namespace ShardingCore.Core.RuntimeContexts
GetRequiredService<IShardingBootstrapper>().AutoShardingCreate();
}
private IShardingProvider _shardingProvider;
public IShardingProvider GetIhardingProvider()
{
return _shardingProvider??=GetRequiredService<IShardingProvider>();
}
private IShardingComparer _shardingComparer;
public IShardingComparer GetShardingComparer()
{
@ -111,6 +120,12 @@ namespace ShardingCore.Core.RuntimeContexts
return _virtualDataSource??=GetRequiredService<IVirtualDataSource>();
}
private IDataSourceRouteManager _dataSourceRouteManager;
public IDataSourceRouteManager GetDataSourceRouteManager()
{
return _dataSourceRouteManager??=GetRequiredService<IDataSourceRouteManager>();
}
private ITableRouteManager _tableRouteManager;
public ITableRouteManager GetTableRouteManager()
{
@ -159,6 +174,41 @@ namespace ShardingCore.Core.RuntimeContexts
return _dataSourceInitializer??=GetRequiredService<IDataSourceInitializer>();
}
public void CheckRequirement()
{
if (isCheckRequirement)
return;
lock (CHECK_REQUIREMENT)
{
if (isCheckRequirement)
return;
isCheckRequirement = true;
try
{
var shardingProvider = GetIhardingProvider();
using (var scope = shardingProvider.CreateScope())
{
using (var dbContext = _dbContextCreator.GetShellDbContext(scope.ServiceProvider))
{
if (dbContext == null)
{
throw new ShardingCoreInvalidOperationException(
$"cant get shell db context,plz override {nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)}");
}
}
}
}
catch (Exception ex)
{
throw new ShardingCoreInvalidOperationException(
$"cant get shell db context,plz override {nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)}",
ex);
}
}
}
public void GetOrCreateShardingRuntimeModel(DbContext dbContext)
{
if (isInitModeled) return;
@ -239,7 +289,7 @@ namespace ShardingCore.Core.RuntimeContexts
private void InitFieldValue()
{
GetIhardingProvider();
GetShardingComparer();
GetShardingCompilerExecutor();
GetShardingReadWriteManager();
@ -249,6 +299,7 @@ namespace ShardingCore.Core.RuntimeContexts
GetDbContextCreator();
GetEntityMetadataManager();
GetVirtualDataSource();
GetDataSourceRouteManager();
GetTableRouteManager();
GetShardingTableCreator();
GetRouteTailFactory();

View File

@ -60,6 +60,10 @@ namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
_shardingRuntimeBuilder.UseConfig(shardingConfigure);
return this;
}
public ShardingCoreConfigBuilder<TShardingDbContext> ReplaceService<TService, TImplement>()
{
return ReplaceService<TService, TImplement>(ServiceLifetime.Singleton);
}
public ShardingCoreConfigBuilder<TShardingDbContext> ReplaceService<TService, TImplement>(ServiceLifetime lifetime)
{
_shardingRuntimeBuilder.ReplaceService<TService, TImplement>(lifetime);

View File

@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Exceptions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
{
public interface IVirtualDataSourceRouteManager
{
/// <summary>
/// 获取当前数据源的路由
/// </summary>
/// <returns></returns>
IVirtualDataSourceRoute GetRoute(Type entityType);
/// <summary>
/// 添加分库路由
/// </summary>
/// <param name="virtualDataSourceRoute"></param>
/// <returns></returns>
/// <exception cref="ShardingCoreInvalidOperationException">对象未配置分库</exception>
bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
}
}

View File

@ -40,19 +40,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
/// 默认连接字符串
/// </summary>
string DefaultConnectionString { get;}
/// <summary>
/// 获取路由
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
IVirtualDataSourceRoute GetRoute(Type entityType);
/// <summary>
/// 路由到具体的物理数据源
/// </summary>
/// <param name="entityType"></param>
/// <param name="routeRouteConfig"></param>
/// <returns>data source names</returns>
List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig);
/// <summary>
/// 获取默认的数据源信息

View File

@ -11,6 +11,7 @@ using ShardingCore.Core.ShardingEnumerableQueries;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
@ -33,15 +34,13 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
public IVirtualDataSourceConfigurationParams ConfigurationParams { get; }
public IConnectionStringManager ConnectionStringManager { get; }
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IVirtualDataSourceRouteManager _dataSourceRouteManager;
private readonly IPhysicDataSourcePool _physicDataSourcePool;
public string DefaultDataSourceName { get; private set; }
public string DefaultConnectionString { get; private set; }
public bool UseReadWriteSeparation { get; }
public VirtualDataSource(IEntityMetadataManager entityMetadataManager, IVirtualDataSourceRouteManager dataSourceRouteManager, IVirtualDataSourceConfigurationParams configurationParams,IReadWriteConnectorFactory readWriteConnectorFactory)
public VirtualDataSource( IVirtualDataSourceConfigurationParams configurationParams,IReadWriteConnectorFactory readWriteConnectorFactory)
{
Check.NotNull(configurationParams, nameof(configurationParams));
Check.NotNull(configurationParams.ExtraDataSources, nameof(configurationParams.ExtraDataSources));
@ -55,8 +54,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
{
AddPhysicDataSource(new DefaultPhysicDataSource(extraDataSource.Key, extraDataSource.Value, false));
}
_entityMetadataManager = entityMetadataManager;
_dataSourceRouteManager = dataSourceRouteManager;
UseReadWriteSeparation = ConfigurationParams.UseReadWriteSeparation();
if (UseReadWriteSeparation)
{
@ -90,42 +87,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
}
}
public IVirtualDataSourceRoute GetRoute(Type entityType)
{
return _dataSourceRouteManager.GetRoute(entityType);
}
public List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig)
{
if (!_entityMetadataManager.IsShardingDataSource(entityType))
return new List<string>(1) { DefaultDataSourceName };
var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType);
if (routeRouteConfig.UseQueryable())
return virtualDataSourceRoute.RouteWithPredicate(routeRouteConfig.GetQueryable(), true);
if (routeRouteConfig.UsePredicate())
{
var shardingEmptyEnumerableQuery = (IShardingEmptyEnumerableQuery)Activator.CreateInstance(typeof(ShardingEmptyEnumerableQuery<>).MakeGenericType(entityType), routeRouteConfig.GetPredicate());
return virtualDataSourceRoute.RouteWithPredicate(shardingEmptyEnumerableQuery.EmptyQueryable(), false);
}
object shardingKeyValue = null;
if (routeRouteConfig.UseValue())
shardingKeyValue = routeRouteConfig.GetShardingKeyValue();
if (routeRouteConfig.UseEntity())
{
shardingKeyValue = routeRouteConfig.GetShardingDataSource().GetPropertyValue(virtualDataSourceRoute.EntityMetadata.ShardingDataSourceProperty.Name);
}
if (shardingKeyValue != null)
{
var dataSourceName = virtualDataSourceRoute.RouteWithValue(shardingKeyValue);
return new List<string>(1) { dataSourceName };
}
throw new NotImplementedException(nameof(ShardingDataSourceRouteConfig));
}
/// <summary>
/// 获取默认数据源
/// </summary>

View File

@ -1,53 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.ShardingEnumerableQueries;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
{
public class VirtualDataSourceRouteManager : IVirtualDataSourceRouteManager
{
private readonly ConcurrentDictionary<Type, IVirtualDataSourceRoute> _dataSourceVirtualRoutes = new ConcurrentDictionary<Type, IVirtualDataSourceRoute>();
public IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity : class
{
return (IVirtualDataSourceRoute<TEntity>)GetRoute(typeof(TEntity));
}
public IVirtualDataSourceRoute GetRoute(Type entityType)
{
// if (!_entityMetadataManager.IsShardingDataSource(entityType))
// throw new ShardingCoreInvalidOperationException(
// $"entity type :[{entityType.FullName}] not configure sharding data source");
if (!_dataSourceVirtualRoutes.TryGetValue(entityType, out var dataSourceVirtualRoute))
throw new ShardingCoreInvalidOperationException(
$"entity type :[{entityType.FullName}] not found virtual data source route");
return dataSourceVirtualRoute;
}
/// <summary>
/// 添加分库路由
/// </summary>
/// <param name="virtualDataSourceRoute"></param>
/// <returns></returns>
/// <exception cref="ShardingCoreInvalidOperationException">对象未配置分库</exception>
public bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute)
{
if (!virtualDataSourceRoute.EntityMetadata.IsShardingDataSource())
throw new ShardingCoreInvalidOperationException($"{virtualDataSourceRoute.EntityMetadata.EntityType.FullName} should configure sharding data source");
return _dataSourceVirtualRoutes.TryAdd(virtualDataSourceRoute.EntityMetadata.EntityType, virtualDataSourceRoute);
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Exceptions;
namespace ShardingCore.Core.VirtualRoutes.Abstractions
{
public interface IDataSourceRouteManager
{
/// <summary>
/// 实体对象是否存在分表路由
/// </summary>
/// <param name="entityType"></param>
/// <returns></returns>
bool HasRoute(Type entityType);
/// <summary>
/// 路由到具体的物理数据源
/// </summary>
/// <param name="entityType"></param>
/// <param name="routeRouteConfig"></param>
/// <returns>data source names</returns>
List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig);
/// <summary>
/// 获取当前数据源的路由
/// </summary>
/// <returns></returns>
IVirtualDataSourceRoute GetRoute(Type entityType);
/// <summary>
/// 添加分库路由
/// </summary>
/// <param name="virtualDataSourceRoute"></param>
/// <returns></returns>
/// <exception cref="ShardingCoreInvalidOperationException">对象未配置分库</exception>
bool AddDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
}
}

View File

@ -0,0 +1,81 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.ShardingEnumerableQueries;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes
{
public class DataSourceRouteManager:IDataSourceRouteManager
{
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IVirtualDataSource _virtualDataSource;
private readonly ConcurrentDictionary<Type, IVirtualDataSourceRoute> _dataSourceVirtualRoutes = new ConcurrentDictionary<Type, IVirtualDataSourceRoute>();
public DataSourceRouteManager(IEntityMetadataManager entityMetadataManager,IVirtualDataSource virtualDataSource)
{
_entityMetadataManager = entityMetadataManager;
_virtualDataSource = virtualDataSource;
}
public bool HasRoute(Type entityType)
{
return _dataSourceVirtualRoutes.ContainsKey(entityType);
}
public List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig)
{
if (!_entityMetadataManager.IsShardingDataSource(entityType))
return new List<string>(1) { _virtualDataSource.DefaultDataSourceName };
var virtualDataSourceRoute = GetRoute(entityType);
if (routeRouteConfig.UseQueryable())
return virtualDataSourceRoute.RouteWithPredicate(routeRouteConfig.GetQueryable(), true);
if (routeRouteConfig.UsePredicate())
{
var shardingEmptyEnumerableQuery = (IShardingEmptyEnumerableQuery)Activator.CreateInstance(typeof(ShardingEmptyEnumerableQuery<>).MakeGenericType(entityType), routeRouteConfig.GetPredicate());
return virtualDataSourceRoute.RouteWithPredicate(shardingEmptyEnumerableQuery.EmptyQueryable(), false);
}
object shardingKeyValue = null;
if (routeRouteConfig.UseValue())
shardingKeyValue = routeRouteConfig.GetShardingKeyValue();
if (routeRouteConfig.UseEntity())
{
shardingKeyValue = routeRouteConfig.GetShardingDataSource().GetPropertyValue(virtualDataSourceRoute.EntityMetadata.ShardingDataSourceProperty.Name);
}
if (shardingKeyValue != null)
{
var dataSourceName = virtualDataSourceRoute.RouteWithValue(shardingKeyValue);
return new List<string>(1) { dataSourceName };
}
throw new NotImplementedException(nameof(ShardingDataSourceRouteConfig));
}
public IVirtualDataSourceRoute GetRoute(Type entityType)
{
if (!_dataSourceVirtualRoutes.TryGetValue(entityType, out var dataSourceVirtualRoute))
throw new ShardingCoreInvalidOperationException(
$"entity type :[{entityType.FullName}] not found virtual data source route");
return dataSourceVirtualRoute;
}
/// <summary>
/// 添加分库路由
/// </summary>
/// <param name="virtualDataSourceRoute"></param>
/// <returns></returns>
/// <exception cref="ShardingCoreInvalidOperationException">对象未配置分库</exception>
public bool AddDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute)
{
if (!virtualDataSourceRoute.EntityMetadata.IsShardingDataSource())
throw new ShardingCoreInvalidOperationException($"{virtualDataSourceRoute.EntityMetadata.EntityType.FullName} should configure sharding data source");
return _dataSourceVirtualRoutes.TryAdd(virtualDataSourceRoute.EntityMetadata.EntityType, virtualDataSourceRoute);
}
}
}

View File

@ -26,7 +26,6 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
{
Queryable = queryable;
ShardingDbContext = shardingDbContext;
VirtualDataSource = shardingDbContext.GetVirtualDataSource();
QueryEntities = queryEntities;
}
public Dictionary<Type, IQueryable> QueryEntities { get; }
@ -36,6 +35,5 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
public IQueryable Queryable { get; }
public IShardingDbContext ShardingDbContext { get; }
public IVirtualDataSource VirtualDataSource { get; }
}
}

View File

@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
@ -22,14 +23,17 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
public class DataSourceRouteRuleEngine: IDataSourceRouteRuleEngine
{
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IVirtualDataSource _virtualDataSource;
private readonly IDataSourceRouteManager _dataSourceRouteManager;
public DataSourceRouteRuleEngine(IEntityMetadataManager entityMetadataManager)
public DataSourceRouteRuleEngine(IEntityMetadataManager entityMetadataManager,IVirtualDataSource virtualDataSource,IDataSourceRouteManager dataSourceRouteManager)
{
_entityMetadataManager = entityMetadataManager;
_virtualDataSource = virtualDataSource;
_dataSourceRouteManager = dataSourceRouteManager;
}
public DataSourceRouteResult Route(DataSourceRouteRuleContext routeRuleContext)
{
var virtualDataSource = routeRuleContext.VirtualDataSource;
var dataSourceMaps = new Dictionary<Type, ISet<string>>();
foreach (var queryEntityKv in routeRuleContext.QueryEntities)
@ -37,10 +41,10 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
var queryEntity = queryEntityKv.Key;
if (!_entityMetadataManager.IsShardingDataSource(queryEntity))
{
dataSourceMaps.Add(queryEntity, new HashSet<string>() { virtualDataSource.DefaultDataSourceName });
dataSourceMaps.Add(queryEntity, new HashSet<string>() { _virtualDataSource.DefaultDataSourceName });
continue;
}
var dataSourceConfigs = virtualDataSource.RouteTo(queryEntity, new ShardingDataSourceRouteConfig(queryEntityKv.Value??routeRuleContext.Queryable));
var dataSourceConfigs = _dataSourceRouteManager.RouteTo(queryEntity, new ShardingDataSourceRouteConfig(queryEntityKv.Value??routeRuleContext.Queryable));
if (!dataSourceMaps.ContainsKey(queryEntity))
{
dataSourceMaps.Add(queryEntity, dataSourceConfigs.ToHashSet());

View File

@ -39,7 +39,8 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
/// <returns></returns>
TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey);
/// <summary>
/// 获取所有的目前数据库存在的尾巴,仅启动时调用
/// 获取所有的目前数据库存在的尾巴,每次路由都会调用
/// 请不要在此处添加过于复杂的操作
/// get all tails in the db
/// </summary>
/// <returns></returns>

View File

@ -31,6 +31,7 @@ namespace ShardingCore.DynamicDataSources
private readonly IShardingRouteConfigOptions _routeConfigOptions;
private readonly IVirtualDataSource _virtualDataSource;
private readonly IRouteTailFactory _routeTailFactory;
private readonly IDataSourceRouteManager _dataSourceRouteManager;
private readonly ITableRouteManager _tableRouteManager;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IShardingTableCreator _tableCreator;
@ -42,6 +43,7 @@ namespace ShardingCore.DynamicDataSources
IShardingRouteConfigOptions routeConfigOptions,
IVirtualDataSource virtualDataSource,
IRouteTailFactory routeTailFactory,
IDataSourceRouteManager dataSourceRouteManager,
ITableRouteManager tableRouteManager,
IEntityMetadataManager entityMetadataManager,
IShardingTableCreator shardingTableCreator,
@ -52,6 +54,7 @@ namespace ShardingCore.DynamicDataSources
_routeConfigOptions = routeConfigOptions;
_virtualDataSource = virtualDataSource;
_routeTailFactory = routeTailFactory;
_dataSourceRouteManager = dataSourceRouteManager;
_tableRouteManager = tableRouteManager;
_entityMetadataManager = entityMetadataManager;
_tableCreator = shardingTableCreator;
@ -90,7 +93,7 @@ namespace ShardingCore.DynamicDataSources
//非默认数据源
if (_entityMetadataManager.IsShardingDataSource(entityType))
{
var virtualDataSourceRoute = _virtualDataSource.GetRoute(entityType);
var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType);
if (virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName))
{
if (_entityMetadataManager.IsShardingTable(entityType))

View File

@ -46,18 +46,19 @@ namespace ShardingCore.EFCores
_shardingRuntimeContext = context.GetService<IShardingRuntimeContext>();
}
#endif
private IVirtualDataSource _virtualDataSource;
protected IVirtualDataSource VirtualDataSource
private IDataSourceRouteManager _dataSourceRouteManager;
protected IDataSourceRouteManager DataSourceRouteManager
{
get
{
if (null == _virtualDataSource)
if (null == _dataSourceRouteManager)
{
_virtualDataSource = _context.GetVirtualDataSource();
_dataSourceRouteManager = _shardingRuntimeContext.GetDataSourceRouteManager();
}
return _virtualDataSource;
return _dataSourceRouteManager;
}
}
@ -425,9 +426,7 @@ namespace ShardingCore.EFCores
private string GetDataSourceName(object shardingKeyValue)
{
if (!EntityMetadataManager.IsShardingDataSource(typeof(TEntity)))
return VirtualDataSource.DefaultDataSourceName;
return VirtualDataSource.GetDataSourceName<TEntity>(shardingKeyValue);
return DataSourceRouteManager.GetDataSourceName<TEntity>(shardingKeyValue);
}
}
}

View File

@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
namespace ShardingCore.Extensions
@ -18,26 +19,26 @@ namespace ShardingCore.Extensions
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public static class VirtualDataSourceExtension
public static class DataSourceRouteManagerExtension
{
public static string GetDataSourceName<TEntity>(this IVirtualDataSource virtualDataSource,TEntity entity)where TEntity : class
public static string GetDataSourceName<TEntity>(this IDataSourceRouteManager dataSourceRouteManager,TEntity entity)where TEntity : class
{
return virtualDataSource.RouteTo(entity.GetType(),
return dataSourceRouteManager.RouteTo(entity.GetType(),
new ShardingDataSourceRouteConfig(shardingDataSource: entity))[0];
}
public static List<string> GetDataSourceNames<TEntity>(this IVirtualDataSource virtualDataSource, Expression<Func<TEntity, bool>> where)
public static List<string> GetDataSourceNames<TEntity>(this IDataSourceRouteManager dataSourceRouteManager, Expression<Func<TEntity, bool>> where)
where TEntity : class
{
return virtualDataSource.RouteTo(typeof(TEntity),new ShardingDataSourceRouteConfig(predicate: where))
return dataSourceRouteManager.RouteTo(typeof(TEntity),new ShardingDataSourceRouteConfig(predicate: where))
.ToList();
}
public static string GetDataSourceName<TEntity>(this IVirtualDataSource virtualDataSource, object shardingKeyValue) where TEntity : class
public static string GetDataSourceName<TEntity>(this IDataSourceRouteManager dataSourceRouteManager, object shardingKeyValue) where TEntity : class
{
return virtualDataSource.RouteTo(typeof(TEntity),
return dataSourceRouteManager.RouteTo(typeof(TEntity),
new ShardingDataSourceRouteConfig(shardingKeyValue:shardingKeyValue))[0];
}
}
}

View File

@ -92,6 +92,7 @@ namespace ShardingCore.Extensions
var entityType = typeof(TEntity);
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
var virtualDataSource = shardingDbContext.GetVirtualDataSource();
var dataSourceRouteManager = shardingRuntimeContext.GetDataSourceRouteManager();
var tableRouteManager =shardingRuntimeContext.GetTableRouteManager();
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();
var dataSourceNames = new Dictionary<string, Dictionary<string, BulkDicEntry<TEntity>>>();
@ -127,7 +128,7 @@ namespace ShardingCore.Extensions
}
else
{
var virtualDataSourceRoute = virtualDataSource.GetRoute(entityType);
var virtualDataSourceRoute = dataSourceRouteManager.GetRoute(entityType);
var allDataSourceNames = virtualDataSourceRoute.GetAllDataSourceNames().ToHashSet();
var entityMetadata = entityMetadataManager.TryGet(entityType);
@ -245,12 +246,12 @@ namespace ShardingCore.Extensions
where TShardingDbContext : DbContext, IShardingDbContext
{
var shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>();
var virtualDataSource = shardingDbContext.GetVirtualDataSource();
var routeTailFactory = shardingRuntimeContext.GetRouteTailFactory();
var dataSourceRouteManager = shardingRuntimeContext.GetDataSourceRouteManager();
var tableRouteManager = shardingRuntimeContext.GetTableRouteManager();// (IVirtualTableManager)ShardingContainer.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContext.GetType()));
var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager();// (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContext.GetType()));
var dataSourceNames = virtualDataSource.GetDataSourceNames(where);
var dataSourceNames = dataSourceRouteManager.GetDataSourceNames(where);
var result = new Dictionary<string, LinkedList<DbContext>>();
var entityType = typeof(TEntity);

View File

@ -15,8 +15,4 @@ namespace ShardingCore.Sharding.Abstractions
{
StreamMergeContext Create(IMergeQueryCompilerContext mergeQueryCompilerContext);
}
// public interface IStreamMergeContextFactory<TShardingDbContext> : IStreamMergeContextFactory where TShardingDbContext:DbContext,IShardingDbContext
// {
// }
}

View File

@ -18,5 +18,7 @@ namespace ShardingCore.Sharding.MergeContexts
SelectContext GetSelectContext();
GroupByContext GetGroupByContext();
bool IsEmunerableQuery();
string QueryMethodName();
}
}

View File

@ -10,6 +10,6 @@ namespace ShardingCore.Sharding.MergeContexts
public interface IQueryableOptimizeEngine
{
IOptimizeResult Optimize(IMergeQueryCompilerContext mergeQueryCompilerContext, IParseResult parseResult,
IQueryable rewriteQueryable);
IRewriteResult rewriteResult);
}
}

View File

@ -12,6 +12,6 @@ namespace ShardingCore.Sharding.MergeContexts
*/
public interface IQueryableRewriteEngine
{
IQueryable GetRewriteQueryable(IMergeQueryCompilerContext mergeQueryCompilerContext, IParseResult parseResult);
IRewriteResult GetRewriteQueryable(IMergeQueryCompilerContext mergeQueryCompilerContext, IParseResult parseResult);
}
}

View File

@ -11,6 +11,15 @@ namespace ShardingCore.Sharding.MergeContexts
*/
public interface IRewriteResult
{
/// <summary>
/// 最原始的表达式
/// </summary>
/// <returns></returns>
IQueryable GetCombineQueryable();
/// <summary>
/// 被重写后的表达式
/// </summary>
/// <returns></returns>
IQueryable GetRewriteQueryable();
}
}

View File

@ -13,13 +13,22 @@ namespace ShardingCore.Sharding.MergeContexts
private readonly OrderByContext _orderByContext;
private readonly SelectContext _selectContext;
private readonly GroupByContext _groupByContext;
private readonly bool _isEnumerableQuery;
private readonly string _queryMethodName;
public ParseResult(PaginationContext paginationContext, OrderByContext orderByContext, SelectContext selectContext,GroupByContext groupByContext)
public ParseResult(PaginationContext paginationContext,
OrderByContext orderByContext,
SelectContext selectContext,
GroupByContext groupByContext,
bool isEnumerableQuery,
string queryMethodName)
{
_paginationContext = paginationContext;
_orderByContext = orderByContext;
_selectContext = selectContext;
_groupByContext = groupByContext;
_isEnumerableQuery = isEnumerableQuery;
_queryMethodName = queryMethodName;
}
public PaginationContext GetPaginationContext()
@ -42,5 +51,15 @@ namespace ShardingCore.Sharding.MergeContexts
{
return _groupByContext;
}
public bool IsEmunerableQuery()
{
return _isEnumerableQuery;
}
public string QueryMethodName()
{
return _queryMethodName;
}
}
}

View File

@ -19,7 +19,7 @@ namespace ShardingCore.Sharding.MergeContexts
}
public IOptimizeResult Optimize(IMergeQueryCompilerContext mergeQueryCompilerContext, IParseResult parseResult,
IQueryable rewriteQueryable)
IRewriteResult rewriteResult)
{
var shardingDbContext = mergeQueryCompilerContext.GetShardingDbContext();
var maxParallelExecuteCount =

View File

@ -15,12 +15,14 @@ namespace ShardingCore.Sharding.MergeContexts
{
public IParseResult Parse(IMergeQueryCompilerContext mergeQueryCompilerContext)
{
var isEnumerableQuery = mergeQueryCompilerContext.IsEnumerableQuery();
string queryMethodName = isEnumerableQuery ? null : mergeQueryCompilerContext.QueryMethodName();
var combineQueryable = mergeQueryCompilerContext.GetQueryCombineResult().GetCombineQueryable();
var queryableExtraDiscoverVisitor = new QueryableExtraDiscoverVisitor();
queryableExtraDiscoverVisitor.Visit(combineQueryable.Expression);
return new ParseResult(queryableExtraDiscoverVisitor.GetPaginationContext(),
queryableExtraDiscoverVisitor.GetOrderByContext(), queryableExtraDiscoverVisitor.GetSelectContext(),
queryableExtraDiscoverVisitor.GetGroupByContext());
queryableExtraDiscoverVisitor.GetGroupByContext(),isEnumerableQuery,queryMethodName);
}
}
}

View File

@ -32,7 +32,7 @@ namespace ShardingCore.Sharding.MergeContexts
singleEntityMethodNames.Add(nameof(Enumerable.SingleOrDefault));
}
public IQueryable GetRewriteQueryable(IMergeQueryCompilerContext mergeQueryCompilerContext, IParseResult parseResult)
public IRewriteResult GetRewriteQueryable(IMergeQueryCompilerContext mergeQueryCompilerContext, IParseResult parseResult)
{
var paginationContext = parseResult.GetPaginationContext();
var orderByContext = parseResult.GetOrderByContext();
@ -56,8 +56,9 @@ namespace ShardingCore.Sharding.MergeContexts
}
}
var combineQueryable = mergeQueryCompilerContext.GetQueryCombineResult().GetCombineQueryable();
//去除分页,获取前Take+Skip数量
var reWriteQueryable = mergeQueryCompilerContext.GetQueryCombineResult().GetCombineQueryable();
var reWriteQueryable = combineQueryable;
if (take.HasValue)
{
reWriteQueryable = reWriteQueryable.RemoveTake();
@ -158,7 +159,7 @@ namespace ShardingCore.Sharding.MergeContexts
}
return reWriteQueryable;
return new RewriteResult(combineQueryable,reWriteQueryable);
}
}
}

View File

@ -6,7 +6,24 @@ using System.Threading.Tasks;
namespace ShardingCore.Sharding.MergeContexts
{
internal class RewriteResult
internal class RewriteResult:IRewriteResult
{
private readonly IQueryable _combineQueryable;
private readonly IQueryable _rewriteQueryable;
public RewriteResult(IQueryable combineQueryable,IQueryable rewriteQueryable)
{
_combineQueryable = combineQueryable;
_rewriteQueryable = rewriteQueryable;
}
public IQueryable GetCombineQueryable()
{
return _combineQueryable;
}
public IQueryable GetRewriteQueryable()
{
return _rewriteQueryable;
}
}
}

View File

@ -23,7 +23,8 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines.Enumer
{
private readonly long _total;
public ReverseShardingStreamEnumerable(StreamMergeContext streamMergeContext, long total) : base(streamMergeContext)
public ReverseShardingStreamEnumerable(StreamMergeContext streamMergeContext, long total) : base(
streamMergeContext)
{
_total = total;
}
@ -36,18 +37,19 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines.Enumer
protected override IExecutor<IStreamMergeAsyncEnumerator<TEntity>> CreateExecutor0(bool async)
{
var noPaginationNoOrderQueryable = GetStreamMergeContext().GetOriginalQueryable().RemoveSkip().RemoveTake().RemoveAnyOrderBy().As<IQueryable<TEntity>>();
var noPaginationNoOrderQueryable = GetStreamMergeContext().GetOriginalQueryable().RemoveSkip().RemoveTake()
.RemoveAnyOrderBy().As<IQueryable<TEntity>>();
var skip = GetStreamMergeContext().Skip.GetValueOrDefault();
var take = GetStreamMergeContext().Take.HasValue ? GetStreamMergeContext().Take.Value : (_total - skip);
if (take > int.MaxValue)
throw new ShardingCoreException($"not support take more than {int.MaxValue}");
var realSkip = _total - take - skip;
GetStreamMergeContext().ReSetSkip((int)realSkip);
var propertyOrders = GetStreamMergeContext().Orders.Select(o => new PropertyOrder(o.PropertyExpression, !o.IsAsc, o.OwnerType)).ToArray();
GetStreamMergeContext().ReSetOrders(propertyOrders);
var reverseOrderQueryable = noPaginationNoOrderQueryable.Take((int)realSkip + (int)take).OrderWithExpression(propertyOrders);
GetStreamMergeContext().ReverseOrder();
var reverseOrderQueryable = noPaginationNoOrderQueryable.Take((int)realSkip + (int)take)
.OrderWithExpression(GetStreamMergeContext().Orders);
return new ReverseEnumeratorExecutor<TEntity>(GetStreamMergeContext(), GetStreamMergeCombine(),
reverseOrderQueryable, async);
}
}
}
}

View File

@ -33,12 +33,14 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
private readonly IShardingPageManager _shardingPageManager;
private readonly ITableRouteManager _tableRouteManager;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IDataSourceRouteManager _dataSourceRouteManager;
private EnumeratorStreamMergeEngineFactory(StreamMergeContext streamMergeContext)
{
_streamMergeContext = streamMergeContext;
_shardingPageManager = streamMergeContext.ShardingRuntimeContext.GetShardingPageManager();
_tableRouteManager =streamMergeContext.ShardingRuntimeContext.GetTableRouteManager();
_entityMetadataManager = streamMergeContext.ShardingRuntimeContext.GetEntityMetadataManager();
_dataSourceRouteManager = streamMergeContext.ShardingRuntimeContext.GetDataSourceRouteManager();
}
public static EnumeratorStreamMergeEngineFactory<TEntity> Create(StreamMergeContext streamMergeContext)
@ -48,7 +50,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
public IVirtualDataSourceRoute GetRoute(Type entityType)
{
return _streamMergeContext.GetShardingDbContext().GetVirtualDataSource().GetRoute(entityType);
return _dataSourceRouteManager.GetRoute(entityType);
}
public IStreamEnumerable<TEntity> GetStreamEnumerable()
{

View File

@ -1,16 +1,12 @@
// using System.Collections.Generic;
// using Microsoft.EntityFrameworkCore;
// using ShardingCore.Extensions;
// using ShardingCore.Sharding.Abstractions;
// using ShardingCore.Sharding.MergeEngines.Abstractions.InMemoryMerge;
// using System.Linq;
// using System.Threading;
// using System.Threading.Tasks;
// using ShardingCore.Extensions;
// using ShardingCore.Sharding.MergeEngines.Abstractions.InMemoryMerge;
// using ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines;
// using ShardingCore.Sharding.MergeEngines.Executors.Abstractions;
// using ShardingCore.Sharding.MergeEngines.Executors.Methods;
//
// namespace ShardingCore.Sharding.StreamMergeEngines
// namespace ShardingCore.Sharding.MergeEngines
// {
// /*
// * @Author: xjm

View File

@ -0,0 +1,73 @@
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Threading;
// using System.Threading.Tasks;
// using ShardingCore.Extensions;
// using ShardingCore.Sharding.MergeEngines.Abstractions.InMemoryMerge;
// using ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines;
//
// namespace ShardingCore.Sharding.MergeEngines
// {
//
// public class FirstSkipAsyncInMemoryMergeEngine<TEntity> : IEnsureMergeResult<TEntity>
// {
// private readonly StreamMergeContext _streamMergeContext;
//
// public FirstSkipAsyncInMemoryMergeEngine(StreamMergeContext streamMergeContext)
// {
// _streamMergeContext = streamMergeContext;
// }
// // protected override IExecutor<RouteQueryResult<TEntity>> CreateExecutor0(bool async)
// // {
// // return new FirstOrDefaultMethodExecutor<TEntity>(GetStreamMergeContext());
// // }
// //
// // protected override TEntity DoMergeResult0(List<RouteQueryResult<TEntity>> resultList)
// // {
// // var notNullResult = resultList.Where(o => o != null && o.HasQueryResult()).Select(o => o.QueryResult).ToList();
// //
// // if (notNullResult.IsEmpty())
// // return default;
// //
// // var streamMergeContext = GetStreamMergeContext();
// // if (streamMergeContext.Orders.Any())
// // return notNullResult.AsQueryable().OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).FirstOrDefault();
// //
// // return notNullResult.FirstOrDefault();
// // }
// public TEntity MergeResult()
// {
// return MergeResultAsync().WaitAndUnwrapException(false);
// }
//
// public async Task<TEntity> MergeResultAsync(CancellationToken cancellationToken = new CancellationToken())
// {
//
// //将toke改成1
// var asyncEnumeratorStreamMergeEngine = new AsyncEnumeratorStreamMergeEngine<TEntity>(_streamMergeContext);
//
// var list = new List<TEntity>();
// await foreach (var element in asyncEnumeratorStreamMergeEngine.WithCancellation(cancellationToken))
// {
// list.Add(element);
// }
//
// if (list.IsEmpty())
// throw new InvalidOperationException("Sequence contains no elements.");
//
// return list.First();
// }
//
//
// // if (notNullResult.IsEmpty())
// // throw new InvalidOperationException("Sequence contains no elements.");
// //
// // var streamMergeContext = GetStreamMergeContext();
// // if (streamMergeContext.Orders.Any())
// // return notNullResult.AsQueryable().OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).First();
// //
// // return notNullResult.First();
// }
// }
//

View File

@ -0,0 +1,81 @@
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Threading;
// using System.Threading.Tasks;
// using ShardingCore.Extensions;
// using ShardingCore.Sharding.MergeEngines.Abstractions.InMemoryMerge;
// using ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines;
// using ShardingCore.Sharding.MergeEngines.Executors.Abstractions;
// using ShardingCore.Sharding.MergeEngines.Executors.Methods;
// using ShardingCore.Sharding.StreamMergeEngines;
//
// namespace ShardingCore.Sharding.MergeEngines
// {
// /*
// * @Author: xjm
// * @Description:
// * @Date: 2021/8/18 14:22:07
// * @Ver: 1.0
// * @Email: 326308290@qq.com
// */
// internal class LastSkipAsyncInMemoryMergeEngine<TEntity> : IEnsureMergeResult<TEntity>
// {
// private readonly StreamMergeContext _streamMergeContext;
//
// public LastSkipAsyncInMemoryMergeEngine(StreamMergeContext streamMergeContext)
// {
// _streamMergeContext = streamMergeContext;
// }
// // protected override IExecutor<RouteQueryResult<TEntity>> CreateExecutor0(bool async)
// // {
// // return new FirstOrDefaultMethodExecutor<TEntity>(GetStreamMergeContext());
// // }
// //
// // protected override TEntity DoMergeResult0(List<RouteQueryResult<TEntity>> resultList)
// // {
// // var notNullResult = resultList.Where(o => o != null && o.HasQueryResult()).Select(o => o.QueryResult).ToList();
// //
// // if (notNullResult.IsEmpty())
// // return default;
// //
// // var streamMergeContext = GetStreamMergeContext();
// // if (streamMergeContext.Orders.Any())
// // return notNullResult.AsQueryable().OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).FirstOrDefault();
// //
// // return notNullResult.FirstOrDefault();
// // }
// public TEntity MergeResult()
// {
// return MergeResultAsync().WaitAndUnwrapException(false);
// }
//
// public async Task<TEntity> MergeResultAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// //将take改成1
// var asyncEnumeratorStreamMergeEngine = new AsyncEnumeratorStreamMergeEngine<TEntity>(_streamMergeContext);
//
// var list = new List<TEntity>();
// await foreach (var element in asyncEnumeratorStreamMergeEngine.WithCancellation(cancellationToken))
// {
// list.Add(element);
// }
//
// if (list.IsEmpty())
// {
// return default;
// }
// return list.FirstOrDefault();
// }
//
//
// // if (notNullResult.IsEmpty())
// // throw new InvalidOperationException("Sequence contains no elements.");
// // var streamMergeContext = GetStreamMergeContext();
// // if (streamMergeContext.Orders.Any())
// // return notNullResult.AsQueryable().OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).Last();
// //
// // return notNullResult.Last();
// }
// }
//

View File

@ -37,6 +37,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
private readonly ConcurrentDictionary<string, IDataSourceDbContext> _dbContextCaches = new ConcurrentDictionary<string, IDataSourceDbContext>();
private readonly IShardingRuntimeContext _shardingRuntimeContext;
private readonly IVirtualDataSource _virtualDataSource;
private readonly IDataSourceRouteManager _dataSourceRouteManager;
private readonly ITableRouteManager _tableRouteManager;
private readonly IDbContextCreator _dbContextCreator;
private readonly IRouteTailFactory _routeTailFactory;
@ -64,6 +65,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
_shardingRuntimeContext = shardingDbContext.GetRequireService<IShardingRuntimeContext>();
_shardingRuntimeContext.GetOrCreateShardingRuntimeModel(shardingDbContext);
_virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource();
_dataSourceRouteManager = _shardingRuntimeContext.GetDataSourceRouteManager();
_tableRouteManager = _shardingRuntimeContext.GetTableRouteManager();
_dbContextCreator = _shardingRuntimeContext.GetDbContextCreator();
_entityMetadataManager = _shardingRuntimeContext.GetEntityMetadataManager();
@ -125,9 +127,7 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
private string GetDataSourceName<TEntity>(TEntity entity) where TEntity : class
{
if (!_entityMetadataManager.IsShardingDataSource(entity.GetType()))
return _virtualDataSource.DefaultDataSourceName;
return _virtualDataSource.GetDataSourceName(entity);
return _dataSourceRouteManager.GetDataSourceName(entity);
}
private string GetTableTail<TEntity>(TEntity entity) where TEntity : class

View File

@ -44,6 +44,7 @@ namespace ShardingCore.Sharding
public IQueryable RewriteQueryable { get; }
public IOptimizeResult OptimizeResult { get; }
private readonly IRewriteResult _rewriteResult;
private readonly IRouteTailFactory _routeTailFactory;
public int? Skip { get; private set; }
@ -84,15 +85,16 @@ namespace ShardingCore.Sharding
public StreamMergeContext(IMergeQueryCompilerContext mergeQueryCompilerContext,IParseResult parseResult,IQueryable rewriteQueryable,IOptimizeResult optimizeResult,
public StreamMergeContext(IMergeQueryCompilerContext mergeQueryCompilerContext,IParseResult parseResult,IRewriteResult rewriteResult,IOptimizeResult optimizeResult,
IRouteTailFactory routeTailFactory,ITrackerManager trackerManager,IShardingRouteConfigOptions shardingRouteConfigOptions)
{
MergeQueryCompilerContext = mergeQueryCompilerContext;
ShardingRuntimeContext = ((DbContext)mergeQueryCompilerContext.GetShardingDbContext())
.GetRequireService<IShardingRuntimeContext>();
ParseResult = parseResult;
RewriteQueryable = rewriteQueryable;
RewriteQueryable = rewriteResult.GetRewriteQueryable();
OptimizeResult = optimizeResult;
_rewriteResult = rewriteResult;
_routeTailFactory = routeTailFactory;
QueryEntities= MergeQueryCompilerContext.GetQueryEntities().Keys.ToHashSet();
_trackerManager =trackerManager;
@ -345,5 +347,14 @@ namespace ShardingCore.Sharding
{
return Take;
}
public void ReverseOrder()
{
if (Orders.Any())
{
var propertyOrders = Orders.Select(o => new PropertyOrder(o.PropertyExpression, !o.IsAsc, o.OwnerType)).ToArray();
ReSetOrders(propertyOrders);
}
}
}
}

View File

@ -40,19 +40,19 @@ namespace ShardingCore.Sharding
}
public StreamMergeContext Create(IMergeQueryCompilerContext mergeQueryCompilerContext)
{
var parseResult = _queryableParseEngine.Parse(mergeQueryCompilerContext);
var rewriteQueryable = _queryableRewriteEngine.GetRewriteQueryable(mergeQueryCompilerContext, parseResult);
var optimizeResult = _queryableOptimizeEngine.Optimize(mergeQueryCompilerContext, parseResult, rewriteQueryable);
return new StreamMergeContext(mergeQueryCompilerContext, parseResult, rewriteQueryable,optimizeResult, _routeTailFactory,_trackerManager,_shardingRouteConfigOptions);
var rewriteResult = _queryableRewriteEngine.GetRewriteQueryable(mergeQueryCompilerContext, parseResult);
var optimizeResult = _queryableOptimizeEngine.Optimize(mergeQueryCompilerContext, parseResult, rewriteResult);
return new StreamMergeContext(mergeQueryCompilerContext, parseResult, rewriteResult,optimizeResult, _routeTailFactory,_trackerManager,_shardingRouteConfigOptions);
}
private void CheckMergeContext(IMergeQueryCompilerContext mergeQueryCompilerContext,IParseResult parseResult,IQueryable rewriteQueryable,IOptimizeResult optimizeResult)
{
if (!mergeQueryCompilerContext.IsEnumerableQuery())
{
// Queries performing 'LastOrDefault' operation must have a deterministic sort order. Rewrite the query to apply an 'OrderBy' operation on the sequence before calling 'LastOrDefault'
}
}
}

View File

@ -33,6 +33,7 @@ using ShardingCore.Core.UnionAllMergeShardingProviders;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.DynamicDataSources;
using ShardingCore.Sharding.MergeContexts;
@ -115,7 +116,7 @@ namespace ShardingCore
services.TryAddSingleton<IShardingTableCreator, ShardingTableCreator>();
//虚拟数据源管理
services.TryAddSingleton<IVirtualDataSource, VirtualDataSource>();
services.TryAddSingleton<IVirtualDataSourceRouteManager, VirtualDataSourceRouteManager>();
services.TryAddSingleton<IDataSourceRouteManager, DataSourceRouteManager>();
services.TryAddSingleton<IDataSourceRouteRuleEngine, DataSourceRouteRuleEngine>();
services.TryAddSingleton<IDataSourceRouteRuleEngineFactory, DataSourceRouteRuleEngineFactory>();
//读写分离链接创建工厂
@ -204,12 +205,13 @@ namespace ShardingCore
/// <summary>
/// 使用自动创建表
/// 启用定时任务自动创建表
/// </summary>
/// <param name="serviceProvider"></param>
public static void UseAutoShardingCreate(this IServiceProvider serviceProvider)
{
var shardingRuntimeContext = serviceProvider.GetRequiredService<IShardingRuntimeContext>();
shardingRuntimeContext.CheckRequirement();
shardingRuntimeContext.AutoShardingCreate();
}
/// <summary>
@ -219,6 +221,7 @@ namespace ShardingCore
public static void UseAutoTryCompensateTable(this IServiceProvider serviceProvider)
{
var shardingRuntimeContext = serviceProvider.GetRequiredService<IShardingRuntimeContext>();
shardingRuntimeContext.CheckRequirement();
var virtualDataSource = shardingRuntimeContext.GetVirtualDataSource();
var dataSourceInitializer = shardingRuntimeContext.GetDataSourceInitializer();
var allDataSourceNames = virtualDataSource.GetAllDataSourceNames();

View File

@ -13,6 +13,7 @@ using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.ServiceProviders;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
using ShardingCore.Extensions;
using ShardingCore.Jobs.Abstaractions;
@ -107,6 +108,7 @@ namespace ShardingCore.VirtualRoutes.Abstractions
var entityMetadataManager = RouteShardingProvider.GetRequiredService<IEntityMetadataManager>();
var tableCreator = RouteShardingProvider.GetRequiredService<IShardingTableCreator>();
var virtualDataSource = RouteShardingProvider.GetRequiredService<IVirtualDataSource>();
var dataSourceRouteManager = RouteShardingProvider.GetRequiredService<IDataSourceRouteManager>();
var now = DateTime.Now.AddMinutes(IncrementMinutes);
var tail = ConvertNowToTail(now);
//必须先执行AddPhysicTable在进行CreateTable
@ -114,7 +116,7 @@ namespace ShardingCore.VirtualRoutes.Abstractions
ISet<string> dataSources = new HashSet<string>();
if (entityMetadataManager.IsShardingDataSource(typeof(TEntity)))
{
var virtualDataSourceRoute = virtualDataSource.GetRoute(typeof(TEntity));
var virtualDataSourceRoute = dataSourceRouteManager.GetRoute(typeof(TEntity));
foreach (var dataSourceName in virtualDataSourceRoute.GetAllDataSourceNames())
{
dataSources.Add(dataSourceName);