完成多配置sharding编译[#73]
This commit is contained in:
parent
819b4711af
commit
c1de855bb9
|
@ -129,7 +129,7 @@ namespace ShardingCore6x
|
|||
_streamMergeContextFactory =
|
||||
ShardingContainer.GetService<IStreamMergeContextFactory<DefaultShardingDbContext>>();
|
||||
_actualConnectionStringManager = new ActualConnectionStringManager<DefaultShardingDbContext>();
|
||||
_virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<DefaultShardingDbContext>>();
|
||||
_virtualDataSource = ShardingContainer.GetRequiredVirtualDataSourceManager<DefaultShardingDbContext>().GetVirtualDataSource();
|
||||
_dataSourceRouteRuleEngineFactory = ShardingContainer.GetService<IDataSourceRouteRuleEngineFactory<DefaultShardingDbContext>>();
|
||||
_tableRouteRuleEngineFactory = ShardingContainer.GetService<ITableRouteRuleEngineFactory<DefaultShardingDbContext>>();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -20,17 +21,17 @@ namespace Sample.SqlServer.Controllers
|
|||
public class CreateTableController : ControllerBase
|
||||
{
|
||||
private readonly IShardingTableCreator<DefaultShardingDbContext> _tableCreator;
|
||||
private readonly IVirtualDataSource<DefaultShardingDbContext> _virtualDataSource;
|
||||
private readonly IVirtualDataSourceManager<DefaultShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IVirtualTableManager<DefaultShardingDbContext> _virtualTableManager;
|
||||
private readonly IEntityMetadataManager<DefaultShardingDbContext> _entityMetadataManager;
|
||||
|
||||
public CreateTableController(IShardingTableCreator<DefaultShardingDbContext> tableCreator,
|
||||
IVirtualDataSource<DefaultShardingDbContext> virtualDataSource,
|
||||
IVirtualDataSourceManager<DefaultShardingDbContext> virtualDataSourceManager,
|
||||
IVirtualTableManager<DefaultShardingDbContext> virtualTableManager,
|
||||
IEntityMetadataManager<DefaultShardingDbContext> entityMetadataManager)
|
||||
{
|
||||
_tableCreator = tableCreator;
|
||||
_virtualDataSource = virtualDataSource;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
|
@ -41,7 +42,7 @@ namespace Sample.SqlServer.Controllers
|
|||
if (isShardingTable)
|
||||
{
|
||||
#region 完全可以用脚本实现这段代码
|
||||
var defaultDataSourceName = _virtualDataSource.DefaultDataSourceName;
|
||||
var defaultDataSourceName = _virtualDataSourceManager.GetVirtualDataSource().DefaultDataSourceName;
|
||||
try
|
||||
{
|
||||
_tableCreator.CreateTable<SysUserMod>(defaultDataSourceName, "09");
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace Sample.SqlServerShardingAll.Controllers
|
|||
public async Task<IActionResult> Query()
|
||||
{
|
||||
#region 动态数据源
|
||||
var virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<MyDbContext>>();
|
||||
|
||||
var virtualDataSource = ShardingContainer.GetRequiredVirtualDataSource<MyDbContext>();
|
||||
|
||||
var virtualDataSourceRoute1 = virtualDataSource.GetRoute(typeof(Order));
|
||||
virtualDataSourceRoute1.AddDataSourceName("D");
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Sample.SqlServerShardingDataSource
|
|||
public static void CreateSubDb(string dataSourceName, string connectionString)
|
||||
{
|
||||
var _entityMetadataManager = ShardingContainer.GetService<IEntityMetadataManager<MyDbContext>>();
|
||||
var _virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<MyDbContext>>();
|
||||
var _virtualDataSource = ShardingContainer.GetRequiredVirtualDataSource<MyDbContext>();
|
||||
var _virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<MyDbContext>>();
|
||||
var _tableCreator = ShardingContainer.GetService<IShardingTableCreator<MyDbContext>>();
|
||||
|
||||
|
|
|
@ -36,28 +36,64 @@ namespace Sample.SqlServerShardingTable
|
|||
{
|
||||
|
||||
services.AddControllers();
|
||||
services.AddShardingDbContext<MyDbContext>((conStr, builder) =>
|
||||
//services.AddShardingDbContext<MyDbContext>((conStr, builder) =>
|
||||
// {
|
||||
// builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
|
||||
// }).Begin(op =>
|
||||
// {
|
||||
// //如果您使用code-first建议选择false
|
||||
// op.CreateShardingTableOnStart = true;
|
||||
// //如果您使用code-first建议修改为fsle
|
||||
// op.EnsureCreatedWithOutShardingTable = true;
|
||||
// //当无法获取路由时会返回默认值而不是报错
|
||||
// op.ThrowIfQueryRouteNotMatch = true;
|
||||
// }).AddShardingTransaction((connection, builder) =>
|
||||
// {
|
||||
// builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
|
||||
// }).AddDefaultDataSource("ds0",
|
||||
// "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;")
|
||||
// .AddShardingTableRoute(op =>
|
||||
// {
|
||||
// op.AddShardingTableRoute<SysUserVirtualTableRoute>();
|
||||
// op.AddShardingTableRoute<OrderVirtualTableRoute>();
|
||||
// op.AddShardingTableRoute<MultiShardingOrderVirtualTableRoute>();
|
||||
// }).AddReadWriteSeparation(sp =>
|
||||
// {
|
||||
// return new Dictionary<string, IEnumerable<string>>()
|
||||
// {
|
||||
// {
|
||||
// "ds0", new List<string>()
|
||||
// {
|
||||
// "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;"
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// },ReadStrategyEnum.Loop,defaultEnable:true).End();
|
||||
services.AddShardingDbContext<MyDbContext>().AddEntityConfig(op =>
|
||||
{
|
||||
//如果您使用code-first建议选择false
|
||||
op.CreateShardingTableOnStart = true;
|
||||
//如果您使用code-first建议修改为fsle
|
||||
op.EnsureCreatedWithOutShardingTable = true;
|
||||
//当无法获取路由时会返回默认值而不是报错
|
||||
op.ThrowIfQueryRouteNotMatch = true;
|
||||
op.AddShardingTableRoute<SysUserVirtualTableRoute>();
|
||||
op.AddShardingTableRoute<OrderVirtualTableRoute>();
|
||||
op.AddShardingTableRoute<MultiShardingOrderVirtualTableRoute>();
|
||||
}).AddConfig(op =>
|
||||
{
|
||||
op.ConfigId = "a";
|
||||
op.UseShardingQuery((conStr, builder) =>
|
||||
{
|
||||
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
|
||||
}).Begin(op =>
|
||||
{
|
||||
//如果您使用code-first建议选择false
|
||||
op.CreateShardingTableOnStart = true;
|
||||
//如果您使用code-first建议修改为fsle
|
||||
op.EnsureCreatedWithOutShardingTable = true;
|
||||
//当无法获取路由时会返回默认值而不是报错
|
||||
op.ThrowIfQueryRouteNotMatch = true;
|
||||
}).AddShardingTransaction((connection, builder) =>
|
||||
});
|
||||
op.UseShardingTransaction((connection, builder) =>
|
||||
{
|
||||
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
|
||||
}).AddDefaultDataSource("ds0",
|
||||
"Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;")
|
||||
.AddShardingTableRoute(op =>
|
||||
{
|
||||
op.AddShardingTableRoute<SysUserVirtualTableRoute>();
|
||||
op.AddShardingTableRoute<OrderVirtualTableRoute>();
|
||||
op.AddShardingTableRoute<MultiShardingOrderVirtualTableRoute>();
|
||||
}).AddReadWriteSeparation(sp =>
|
||||
});
|
||||
op.AddDefaultDataSource("ds0",
|
||||
"Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;");
|
||||
op.AddReadWriteSeparation(sp =>
|
||||
{
|
||||
return new Dictionary<string, IEnumerable<string>>()
|
||||
{
|
||||
|
@ -68,7 +104,8 @@ namespace Sample.SqlServerShardingTable
|
|||
}
|
||||
}
|
||||
};
|
||||
},ReadStrategyEnum.Loop,defaultEnable:true).End();
|
||||
}, ReadStrategyEnum.Loop, defaultEnable: true);
|
||||
}).EnsureConfig();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
|
|
@ -21,6 +21,7 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
|
@ -42,14 +43,17 @@ namespace ShardingCore.Bootstrapers
|
|||
private readonly string _virtualTableName;
|
||||
private readonly Expression<Func<TEntity,bool>> _queryFilterExpression;
|
||||
private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private readonly IVirtualDataSourceManager<TShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _virtualDataSourceRouteManager;
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> _logger;
|
||||
|
||||
public EntityMetadataInitializer(EntityMetadataEnsureParams entityMetadataEnsureParams
|
||||
, IShardingConfigOption<TShardingDbContext> shardingConfigOption,
|
||||
IVirtualDataSource<TShardingDbContext> virtualDataSource,IVirtualTableManager<TShardingDbContext> virtualTableManager,
|
||||
IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager,
|
||||
IVirtualDataSourceRouteManager<TShardingDbContext> virtualDataSourceRouteManager,
|
||||
IVirtualTableManager<TShardingDbContext> virtualTableManager,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
|
||||
ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> logger
|
||||
)
|
||||
|
@ -58,7 +62,8 @@ namespace ShardingCore.Bootstrapers
|
|||
_virtualTableName = entityMetadataEnsureParams.VirtualTableName;
|
||||
_queryFilterExpression = entityMetadataEnsureParams.EntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as Expression<Func<TEntity, bool>>;
|
||||
_shardingConfigOption = shardingConfigOption;
|
||||
_virtualDataSource = virtualDataSource;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_logger = logger;
|
||||
|
@ -92,8 +97,7 @@ namespace ShardingCore.Bootstrapers
|
|||
{
|
||||
entityMetadataDataSourceConfiguration.Configure(creatEntityMetadataDataSourceBuilder);
|
||||
}
|
||||
|
||||
_virtualDataSource.AddVirtualDataSourceRoute(dataSourceRoute);
|
||||
_virtualDataSourceRouteManager.AddVirtualDataSourceRoute(dataSourceRoute);
|
||||
entityMetadata.CheckShardingDataSourceMetadata();
|
||||
|
||||
}
|
||||
|
|
|
@ -10,9 +10,12 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.TrackerManagers;
|
||||
using ShardingCore.Core.VirtualDatabase;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
|
@ -54,25 +57,26 @@ namespace ShardingCore.Bootstrapers
|
|||
/// </summary>
|
||||
public class ShardingDbContextBootstrapper<TShardingDbContext> : IShardingDbContextBootstrapper where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private readonly IVirtualDataSourceManager<TShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _entityConfigOptions;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IParallelTableManager<TShardingDbContext> _parallelTableManager;
|
||||
private readonly IDataSourceInitializer<TShardingDbContext> _dataSourceInitializer;
|
||||
private readonly ITrackerManager<TShardingDbContext> _trackerManager;
|
||||
private readonly Type _shardingDbContextType;
|
||||
|
||||
public ShardingDbContextBootstrapper(IShardingConfigOption<TShardingDbContext> shardingConfigOption,
|
||||
public ShardingDbContextBootstrapper(
|
||||
IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager,
|
||||
IShardingEntityConfigOptions<TShardingDbContext> entityConfigOptions,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
|
||||
IVirtualDataSource<TShardingDbContext> virtualDataSource,
|
||||
IParallelTableManager<TShardingDbContext> parallelTableManager,
|
||||
IDataSourceInitializer<TShardingDbContext> dataSourceInitializer,
|
||||
ITrackerManager<TShardingDbContext> trackerManager)
|
||||
{
|
||||
_shardingConfigOption = shardingConfigOption;
|
||||
_shardingDbContextType = typeof(TShardingDbContext);
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_entityConfigOptions = entityConfigOptions;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_virtualDataSource= virtualDataSource;
|
||||
_parallelTableManager = parallelTableManager;
|
||||
_dataSourceInitializer = dataSourceInitializer;
|
||||
_trackerManager = trackerManager;
|
||||
|
@ -82,11 +86,9 @@ namespace ShardingCore.Bootstrapers
|
|||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
_virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(_shardingConfigOption.DefaultDataSourceName, _shardingConfigOption.DefaultConnectionString, true));
|
||||
InitializeEntityMetadata();
|
||||
InitializeParallelTables();
|
||||
InitializeConfigure();
|
||||
_virtualDataSource.CheckVirtualDataSource();
|
||||
}
|
||||
|
||||
private void InitializeEntityMetadata()
|
||||
|
@ -102,8 +104,8 @@ namespace ShardingCore.Bootstrapers
|
|||
var entityType = entity.ClrType;
|
||||
_trackerManager.AddDbContextModel(entityType);
|
||||
//entity.GetAnnotation("")
|
||||
if (_shardingConfigOption.HasVirtualDataSourceRoute(entityType) ||
|
||||
_shardingConfigOption.HasVirtualTableRoute(entityType))
|
||||
if (_entityConfigOptions.HasVirtualDataSourceRoute(entityType) ||
|
||||
_entityConfigOptions.HasVirtualTableRoute(entityType))
|
||||
{
|
||||
var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(_shardingDbContextType, entityType);
|
||||
|
||||
|
@ -119,7 +121,7 @@ namespace ShardingCore.Bootstrapers
|
|||
|
||||
private void InitializeParallelTables()
|
||||
{
|
||||
foreach (var parallelTableGroupNode in _shardingConfigOption.GetParallelTableGroupNodes())
|
||||
foreach (var parallelTableGroupNode in _entityConfigOptions.GetParallelTableGroupNodes())
|
||||
{
|
||||
var parallelTableComparerType = parallelTableGroupNode.GetEntities().FirstOrDefault(o => !_entityMetadataManager.IsShardingTable(o.Type));
|
||||
if (parallelTableComparerType != null)
|
||||
|
@ -133,12 +135,16 @@ namespace ShardingCore.Bootstrapers
|
|||
|
||||
private void InitializeConfigure()
|
||||
{
|
||||
var dataSources = _shardingConfigOption.GetDataSources();
|
||||
foreach (var dataSourceKv in dataSources)
|
||||
var allVirtualDataSources = _virtualDataSourceManager.GetAllVirtualDataSources();
|
||||
foreach (var virtualDataSource in allVirtualDataSources)
|
||||
{
|
||||
var dataSourceName = dataSourceKv.Key;
|
||||
var connectionString = dataSourceKv.Value;
|
||||
_dataSourceInitializer.InitConfigure(dataSourceName, connectionString, true);
|
||||
var dataSources = virtualDataSource.GetDataSources();
|
||||
foreach (var dataSourceKv in dataSources)
|
||||
{
|
||||
var dataSourceName = dataSourceKv.Key;
|
||||
var connectionString = dataSourceKv.Value;
|
||||
_dataSourceInitializer.InitConfigure(virtualDataSource,dataSourceName, connectionString, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,8 +13,7 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
public class DefaultEntityMetadataManager<TShardingDbContext> : IEntityMetadataManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly ConcurrentDictionary<Type, EntityMetadata> _caches =
|
||||
new ConcurrentDictionary<Type, EntityMetadata>();
|
||||
private readonly ConcurrentDictionary<Type, EntityMetadata> _caches =new ();
|
||||
public bool AddEntityMetadata(EntityMetadata entityMetadata)
|
||||
{
|
||||
return _caches.TryAdd(entityMetadata.EntityType, entityMetadata);
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.Core.Internal.PriorityQueues {
|
|||
}
|
||||
|
||||
public T Top() {
|
||||
if (heapLength == 0) throw new OverflowException("queu is empty no element can return");
|
||||
if (heapLength == 0) throw new OverflowException("queue is empty no element can return");
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace ShardingCore.Core.Internal.PriorityQueues {
|
|||
}
|
||||
|
||||
public void Pop() {
|
||||
if (heapLength == 0) throw new OverflowException("优先队列为空时无法执行出队操作");
|
||||
if (heapLength == 0) throw new OverflowException("queue is empty no element can return");
|
||||
--heapLength;
|
||||
swap(0, heapLength);
|
||||
Heap<T>.heapAdjustFromTop(buffer, 0, heapLength, descending,this.comparer);
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations.Abstractions
|
||||
{
|
||||
public interface IShardingConfigurationOptions
|
||||
{
|
||||
public void AddShardingGlobalConfigOptions(ShardingGlobalConfigOptions shardingGlobalConfigOptions);
|
||||
|
||||
public ShardingGlobalConfigOptions[] GetAllShardingGlobalConfigOptions();
|
||||
}
|
||||
|
||||
public interface IShardingConfigurationOptions<TShardingDbContext> : IShardingConfigurationOptions where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.DIExtensions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
|
||||
{
|
||||
public class ShardingEntityConfigBuilder<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly ShardingCoreConfigBuilder<TShardingDbContext> _shardingCoreConfigBuilder;
|
||||
|
||||
public ShardingEntityConfigBuilder(ShardingCoreConfigBuilder<TShardingDbContext> shardingCoreConfigBuilder)
|
||||
{
|
||||
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
|
||||
}
|
||||
|
||||
public ShardingEntityConfigBuilder<TShardingDbContext> AddConfig(Action<ShardingGlobalConfigOptions> shardingGlobalConfigOptionsConfigure)
|
||||
{
|
||||
var shardingGlobalConfigOptions = new ShardingGlobalConfigOptions();
|
||||
shardingGlobalConfigOptionsConfigure?.Invoke(shardingGlobalConfigOptions);
|
||||
if (string.IsNullOrWhiteSpace(shardingGlobalConfigOptions.ConfigId))
|
||||
throw new ArgumentNullException(nameof(shardingGlobalConfigOptions.ConfigId));
|
||||
if (string.IsNullOrWhiteSpace(shardingGlobalConfigOptions.DefaultDataSourceName))
|
||||
throw new ArgumentNullException(
|
||||
$"{nameof(shardingGlobalConfigOptions.DefaultDataSourceName)} plz call {nameof(ShardingGlobalConfigOptions.AddDefaultDataSource)}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(shardingGlobalConfigOptions.DefaultConnectionString))
|
||||
throw new ArgumentNullException(
|
||||
$"{nameof(shardingGlobalConfigOptions.DefaultConnectionString)} plz call {nameof(ShardingGlobalConfigOptions.AddDefaultDataSource)}");
|
||||
|
||||
if (shardingGlobalConfigOptions.ConnectionStringConfigure is null)
|
||||
throw new ArgumentNullException($"plz call {nameof(shardingGlobalConfigOptions.UseShardingQuery)}");
|
||||
if (shardingGlobalConfigOptions.ConnectionConfigure is null)
|
||||
throw new ArgumentNullException(
|
||||
$"plz call {nameof(shardingGlobalConfigOptions.UseShardingTransaction)}");
|
||||
|
||||
if (shardingGlobalConfigOptions.ReplaceShardingComparerFactory == null)
|
||||
{
|
||||
throw new ShardingCoreConfigException($"{nameof(shardingGlobalConfigOptions.ReplaceShardingComparerFactory)} is null");
|
||||
}
|
||||
if (shardingGlobalConfigOptions.MaxQueryConnectionsLimit <= 0)
|
||||
throw new ArgumentException(
|
||||
$"{nameof(shardingGlobalConfigOptions.MaxQueryConnectionsLimit)} should greater than and equal 1");
|
||||
_shardingCoreConfigBuilder.ShardingGlobalConfigOptions.Add(shardingGlobalConfigOptions);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IServiceCollection EnsureConfig()
|
||||
{
|
||||
return DoEnsureConfig(false, ShardingConfigurationStrategyEnum.ThrowIfNull);
|
||||
}
|
||||
|
||||
public IServiceCollection EnsureMultiConfig(ShardingConfigurationStrategyEnum configurationStrategy= ShardingConfigurationStrategyEnum.ThrowIfNull)
|
||||
{
|
||||
return DoEnsureConfig(true, configurationStrategy);
|
||||
}
|
||||
|
||||
private IServiceCollection DoEnsureConfig(bool isMultiConfig,
|
||||
ShardingConfigurationStrategyEnum configurationStrategy)
|
||||
{
|
||||
if (_shardingCoreConfigBuilder.ShardingGlobalConfigOptions.IsEmpty())
|
||||
throw new ArgumentException($"plz call {nameof(AddConfig)} at least once ");
|
||||
if (!isMultiConfig)
|
||||
{
|
||||
if (_shardingCoreConfigBuilder.ShardingGlobalConfigOptions.Count > 1)
|
||||
{
|
||||
throw new ArgumentException($"call {nameof(AddConfig)} at most once ");
|
||||
}
|
||||
}
|
||||
|
||||
var services = _shardingCoreConfigBuilder.Services;
|
||||
services.AddSingleton<IDbContextTypeCollector>(sp => new DbContextTypeCollector<TShardingDbContext>());
|
||||
services.AddSingleton<IShardingEntityConfigOptions<TShardingDbContext>>(sp => _shardingCoreConfigBuilder.ShardingEntityConfigOptions);
|
||||
services.AddSingleton(sp => _shardingCoreConfigBuilder.ShardingEntityConfigOptions);
|
||||
if (!isMultiConfig)
|
||||
{
|
||||
services.AddSingleton<IShardingConfigurationOptions<TShardingDbContext>>(sp =>
|
||||
{
|
||||
var shardingSingleConfigurationOptions = new ShardingSingleConfigurationOptions<TShardingDbContext>();
|
||||
shardingSingleConfigurationOptions.ShardingConfigurationStrategy = configurationStrategy;
|
||||
shardingSingleConfigurationOptions.AddShardingGlobalConfigOptions(_shardingCoreConfigBuilder
|
||||
.ShardingGlobalConfigOptions.First());
|
||||
return shardingSingleConfigurationOptions;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddSingleton<IShardingConfigurationOptions<TShardingDbContext>>(sp =>
|
||||
{
|
||||
var shardingMultiConfigurationOptions = new ShardingMultiConfigurationOptions<TShardingDbContext>();
|
||||
shardingMultiConfigurationOptions.ShardingConfigurationStrategy = configurationStrategy;
|
||||
foreach (var shardingGlobalConfigOptions in _shardingCoreConfigBuilder
|
||||
.ShardingGlobalConfigOptions)
|
||||
{
|
||||
shardingMultiConfigurationOptions.AddShardingGlobalConfigOptions(shardingGlobalConfigOptions);
|
||||
}
|
||||
|
||||
return shardingMultiConfigurationOptions;
|
||||
});
|
||||
}
|
||||
|
||||
services.AddInternalShardingCore();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public interface IShardingEntityConfigOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
bool? CreateShardingTableOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 当查询遇到没有路由被命中时是否抛出错误
|
||||
/// </summary>
|
||||
bool ThrowIfQueryRouteNotMatch { get; set; }
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
bool? IgnoreCreateTableError { get; set; }
|
||||
bool? EnableTableRouteCompileCache { get; set; }
|
||||
bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute;
|
||||
void AddShardingDataSourceRoute(Type routeType);
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute;
|
||||
void AddShardingTableRoute(Type routeType);
|
||||
|
||||
bool HasVirtualTableRoute(Type entityType);
|
||||
|
||||
Type GetVirtualTableRouteType(Type entityType);
|
||||
|
||||
bool HasVirtualDataSourceRoute(Type entityType);
|
||||
|
||||
Type GetVirtualDataSourceRouteType(Type entityType);
|
||||
|
||||
ISet<Type> GetShardingTableRouteTypes();
|
||||
|
||||
ISet<Type> GetShardingDataSourceRouteTypes();
|
||||
|
||||
/// <summary>
|
||||
/// 平行表
|
||||
/// </summary>
|
||||
bool AddParallelTableGroupNode(ParallelTableGroupNode parallelTableGroupNode);
|
||||
ISet<ParallelTableGroupNode> GetParallelTableGroupNodes();
|
||||
}
|
||||
public interface IShardingEntityConfigOptions<TShardingDbContext>: IShardingEntityConfigOptions where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
}
|
||||
public class ShardingEntityConfigOptions<TShardingDbContext> : IShardingEntityConfigOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly Dictionary<Type, Type> _virtualDataSourceRoutes = new Dictionary<Type, Type>();
|
||||
private readonly Dictionary<Type, Type> _virtualTableRoutes = new Dictionary<Type, Type>();
|
||||
public readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
public bool? CreateShardingTableOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 当查询遇到没有路由被命中时是否抛出错误
|
||||
/// </summary>
|
||||
public bool ThrowIfQueryRouteNotMatch { get; set; } = true;
|
||||
public bool? EnableTableRouteCompileCache { get; set; }
|
||||
public bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
public bool? IgnoreCreateTableError { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
public void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute
|
||||
{
|
||||
var routeType = typeof(TRoute);
|
||||
AddShardingDataSourceRoute(routeType);
|
||||
}
|
||||
public void AddShardingDataSourceRoute(Type routeType)
|
||||
{
|
||||
if (!routeType.IsVirtualDataSourceRoute())
|
||||
throw new ShardingCoreInvalidOperationException(routeType.FullName);
|
||||
//获取类型
|
||||
var genericVirtualRoute = routeType.GetInterfaces().FirstOrDefault(it => it.IsInterface && it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IVirtualDataSourceRoute<>)
|
||||
&& it.GetGenericArguments().Any());
|
||||
if (genericVirtualRoute == null)
|
||||
throw new ArgumentException("add sharding route type error not assignable from IVirtualDataSourceRoute<>.");
|
||||
|
||||
var shardingEntityType = genericVirtualRoute.GetGenericArguments()[0];
|
||||
if (shardingEntityType == null)
|
||||
throw new ArgumentException("add sharding table route type error not assignable from IVirtualDataSourceRoute<>");
|
||||
if (!_virtualDataSourceRoutes.ContainsKey(shardingEntityType))
|
||||
{
|
||||
_virtualDataSourceRoutes.Add(shardingEntityType, routeType);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
|
||||
{
|
||||
var routeType = typeof(TRoute);
|
||||
AddShardingTableRoute(routeType);
|
||||
}
|
||||
public void AddShardingTableRoute(Type routeType)
|
||||
{
|
||||
if (!routeType.IsIVirtualTableRoute())
|
||||
throw new ShardingCoreInvalidOperationException(routeType.FullName);
|
||||
//获取类型
|
||||
var genericVirtualRoute = routeType.GetInterfaces().FirstOrDefault(it => it.IsInterface && it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IVirtualTableRoute<>)
|
||||
&& it.GetGenericArguments().Any());
|
||||
if (genericVirtualRoute == null)
|
||||
throw new ArgumentException("add sharding route type error not assignable from IVirtualTableRoute<>.");
|
||||
|
||||
var shardingEntityType = genericVirtualRoute.GetGenericArguments()[0];
|
||||
if (shardingEntityType == null)
|
||||
throw new ArgumentException("add sharding table route type error not assignable from IVirtualTableRoute<>");
|
||||
if (!_virtualTableRoutes.ContainsKey(shardingEntityType))
|
||||
{
|
||||
_virtualTableRoutes.Add(shardingEntityType, routeType);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasVirtualTableRoute(Type entityType)
|
||||
{
|
||||
return _virtualTableRoutes.ContainsKey(entityType);
|
||||
}
|
||||
|
||||
public Type GetVirtualTableRouteType(Type entityType)
|
||||
{
|
||||
if (!_virtualTableRoutes.ContainsKey(entityType))
|
||||
throw new ArgumentException($"{entityType} not found IVirtualTableRoute");
|
||||
return _virtualTableRoutes[entityType];
|
||||
}
|
||||
|
||||
public bool HasVirtualDataSourceRoute(Type entityType)
|
||||
{
|
||||
return _virtualDataSourceRoutes.ContainsKey(entityType);
|
||||
}
|
||||
|
||||
public Type GetVirtualDataSourceRouteType(Type entityType)
|
||||
{
|
||||
if (!_virtualDataSourceRoutes.ContainsKey(entityType))
|
||||
throw new ArgumentException($"{entityType} not found IVirtualDataSourceRoute");
|
||||
return _virtualDataSourceRoutes[entityType];
|
||||
}
|
||||
|
||||
public ISet<Type> GetShardingTableRouteTypes()
|
||||
{
|
||||
return _virtualTableRoutes.Keys.ToHashSet();
|
||||
}
|
||||
|
||||
public ISet<Type> GetShardingDataSourceRouteTypes()
|
||||
{
|
||||
return _virtualDataSourceRoutes.Keys.ToHashSet();
|
||||
}
|
||||
public bool AddParallelTableGroupNode(ParallelTableGroupNode parallelTableGroupNode)
|
||||
{
|
||||
Check.NotNull(parallelTableGroupNode, $"{nameof(parallelTableGroupNode)}");
|
||||
return _parallelTables.Add(parallelTableGroupNode);
|
||||
}
|
||||
public ISet<ParallelTableGroupNode> GetParallelTableGroupNodes()
|
||||
{
|
||||
return _parallelTables;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingGlobalConfigOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
|
||||
public int MaxQueryConnectionsLimit { get; set; } = Environment.ProcessorCount;
|
||||
public ConnectionModeEnum ConnectionMode { get; set; } = ConnectionModeEnum.SYSTEM_AUTO;
|
||||
/// <summary>
|
||||
/// 读写分离配置
|
||||
/// </summary>
|
||||
public ShardingReadWriteSeparationOptions ShardingReadWriteSeparationOptions { get; private set; }
|
||||
/// <summary>
|
||||
/// 默认数据源
|
||||
/// </summary>
|
||||
public string DefaultDataSourceName { get; private set; }
|
||||
/// <summary>
|
||||
/// 默认数据源链接字符串
|
||||
/// </summary>
|
||||
public string DefaultConnectionString { get; private set; }
|
||||
/// <summary>
|
||||
/// 添加默认数据源
|
||||
/// </summary>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void AddDefaultDataSource(string dataSourceName, string connectionString)
|
||||
{
|
||||
DefaultDataSourceName= dataSourceName?? throw new ArgumentNullException(nameof(dataSourceName));
|
||||
DefaultConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
|
||||
}
|
||||
public Func<IServiceProvider, IDictionary<string, string>> DataSourcesConfigure { get; private set; }
|
||||
/// <summary>
|
||||
/// 添加额外数据源
|
||||
/// </summary>
|
||||
/// <param name="extraDataSourceConfigure"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void AddExtraDataSource(Func<IServiceProvider, IDictionary<string, string>> extraDataSourceConfigure)
|
||||
{
|
||||
DataSourcesConfigure= extraDataSourceConfigure ?? throw new ArgumentNullException(nameof(extraDataSourceConfigure));
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加读写分离配置
|
||||
/// </summary>
|
||||
/// <param name="readWriteSeparationConfigure"></param>
|
||||
/// <param name="readStrategyEnum"></param>
|
||||
/// <param name="defaultEnable"></param>
|
||||
/// <param name="defaultPriority"></param>
|
||||
/// <param name="readConnStringGetStrategy"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void AddReadWriteSeparation(
|
||||
Func<IServiceProvider, IDictionary<string, IEnumerable<string>>> readWriteSeparationConfigure,
|
||||
ReadStrategyEnum readStrategyEnum,
|
||||
bool defaultEnable = false,
|
||||
int defaultPriority = 10,
|
||||
ReadConnStringGetStrategyEnum readConnStringGetStrategy = ReadConnStringGetStrategyEnum.LatestFirstTime)
|
||||
{
|
||||
ShardingReadWriteSeparationOptions = new ShardingReadWriteSeparationOptions();
|
||||
ShardingReadWriteSeparationOptions.ReadWriteSeparationConfigure= readWriteSeparationConfigure ?? throw new ArgumentNullException(nameof(readWriteSeparationConfigure));
|
||||
ShardingReadWriteSeparationOptions.ReadStrategy = readStrategyEnum;
|
||||
ShardingReadWriteSeparationOptions.DefaultEnable=defaultEnable;
|
||||
ShardingReadWriteSeparationOptions.DefaultPriority= defaultPriority;
|
||||
ShardingReadWriteSeparationOptions.ReadConnStringGetStrategy= readConnStringGetStrategy;
|
||||
}
|
||||
|
||||
|
||||
public Action<DbConnection, DbContextOptionsBuilder> ConnectionConfigure { get; private set; }
|
||||
public Action<string, DbContextOptionsBuilder> ConnectionStringConfigure { get; private set; }
|
||||
|
||||
|
||||
public void UseShardingQuery(Action<string, DbContextOptionsBuilder> queryConfigure)
|
||||
{
|
||||
ConnectionStringConfigure = queryConfigure ?? throw new ArgumentNullException(nameof(queryConfigure));
|
||||
}
|
||||
public void UseShardingTransaction(Action<DbConnection, DbContextOptionsBuilder> transactionConfigure)
|
||||
{
|
||||
ConnectionConfigure = transactionConfigure ?? throw new ArgumentNullException(nameof(transactionConfigure));
|
||||
}
|
||||
|
||||
public Func<IServiceProvider, IShardingComparer> ReplaceShardingComparerFactory { get; private set; } = sp => new CSharpLanguageShardingComparer();
|
||||
/// <summary>
|
||||
/// 替换默认的比较器
|
||||
/// </summary>
|
||||
/// <param name="newShardingComparerFactory"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
ReplaceShardingComparerFactory = newShardingComparerFactory ?? throw new ArgumentNullException(nameof(newShardingComparerFactory));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingMultiConfigurationOptions<TShardingDbContext> : IShardingConfigurationOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; set; } =
|
||||
ShardingConfigurationStrategyEnum.ThrowIfNull;
|
||||
|
||||
private Dictionary<string, ShardingGlobalConfigOptions> _shardingGlobalConfigOptions = new ();
|
||||
|
||||
public void AddShardingGlobalConfigOptions(ShardingGlobalConfigOptions shardingGlobalConfigOptions)
|
||||
{
|
||||
if (_shardingGlobalConfigOptions.ContainsKey(shardingGlobalConfigOptions.ConfigId))
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add config id:[{shardingGlobalConfigOptions.ConfigId}]");
|
||||
|
||||
_shardingGlobalConfigOptions.Add(shardingGlobalConfigOptions.ConfigId, shardingGlobalConfigOptions);
|
||||
}
|
||||
|
||||
public ShardingGlobalConfigOptions[] GetAllShardingGlobalConfigOptions()
|
||||
{
|
||||
return _shardingGlobalConfigOptions.Values.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingReadWriteSeparationOptions
|
||||
{
|
||||
public Func<IServiceProvider, IDictionary<string, IEnumerable<string>>> ReadWriteSeparationConfigure { get; set; }
|
||||
|
||||
public ReadStrategyEnum ReadStrategy { get; set; } = ReadStrategyEnum.Loop;
|
||||
public bool DefaultEnable { get; set; } = false;
|
||||
public int DefaultPriority { get; set; } = 10;
|
||||
|
||||
public ReadConnStringGetStrategyEnum ReadConnStringGetStrategy { get; set; } =
|
||||
ReadConnStringGetStrategyEnum.LatestFirstTime;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingSingleConfigurationOptions<TShardingDbContext> : IShardingConfigurationOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
||||
private ShardingGlobalConfigOptions _shardingGlobalConfigOptions;
|
||||
public ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; set; } =
|
||||
ShardingConfigurationStrategyEnum.ThrowIfNull;
|
||||
|
||||
public void AddShardingGlobalConfigOptions(ShardingGlobalConfigOptions shardingGlobalConfigOptions)
|
||||
{
|
||||
if (_shardingGlobalConfigOptions != null)
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add {nameof(ShardingGlobalConfigOptions)}");
|
||||
_shardingGlobalConfigOptions= shardingGlobalConfigOptions;
|
||||
}
|
||||
|
||||
public ShardingGlobalConfigOptions[] GetAllShardingGlobalConfigOptions()
|
||||
{
|
||||
return new[] { _shardingGlobalConfigOptions };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public abstract class AbstractVirtualDataSourceConfigurationParams<TShardingDbContext>:IVirtualDataSourceConfigurationParams<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public abstract string ConfigId { get; }
|
||||
public abstract int Priority { get; }
|
||||
public abstract int MaxQueryConnectionsLimit { get; }
|
||||
public abstract ConnectionModeEnum ConnectionMode { get; }
|
||||
public abstract string DefaultDataSourceName { get; }
|
||||
public abstract string DefaultConnectionString { get; }
|
||||
public abstract IDictionary<string, string> ExtraDataSources { get; }
|
||||
public abstract IDictionary<string, IEnumerable<string>> ReadWriteSeparationConfigs { get; }
|
||||
public abstract ReadStrategyEnum? ReadStrategy { get; }
|
||||
public abstract bool? ReadWriteDefaultEnable { get; }
|
||||
public abstract int? ReadWriteDefaultPriority { get; }
|
||||
public abstract ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
public abstract IShardingComparer ShardingComparer { get; }
|
||||
|
||||
|
||||
public abstract DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
|
||||
public abstract DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
|
||||
public virtual bool UseReadWriteSeparation()
|
||||
{
|
||||
return ReadWriteSeparationConfigs.IsNotEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -29,5 +29,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<string> GetAllDataSourceNames();
|
||||
|
||||
IDictionary<string, string> GetDataSources();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public interface IVirtualDataSourceAccessor
|
||||
{
|
||||
VirtualDataSourceContext DataSourceContext { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public interface IVirtualDataSourceConfigurationParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
string ConfigId { get; }
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
int MaxQueryConnectionsLimit { get; }
|
||||
ConnectionModeEnum ConnectionMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认数据源
|
||||
/// </summary>
|
||||
string DefaultDataSourceName { get; }
|
||||
/// <summary>
|
||||
/// 默认数据源链接字符串
|
||||
/// </summary>
|
||||
string DefaultConnectionString { get; }
|
||||
IDictionary<string,string> ExtraDataSources { get; }
|
||||
IDictionary<string, IEnumerable<string>> ReadWriteSeparationConfigs { get; }
|
||||
|
||||
ReadStrategyEnum? ReadStrategy { get; }
|
||||
bool? ReadWriteDefaultEnable { get; }
|
||||
int? ReadWriteDefaultPriority { get; }
|
||||
/// <summary>
|
||||
/// 读写分离链接字符串获取
|
||||
/// </summary>
|
||||
ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
IShardingComparer ShardingComparer { get; }
|
||||
/// <summary>
|
||||
/// 如何根据connectionString 配置 DbContextOptionsBuilder
|
||||
/// </summary>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <param name="dbContextOptionsBuilder"></param>
|
||||
/// <returns></returns>
|
||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString, DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
/// <summary>
|
||||
/// 如何根据dbConnection 配置DbContextOptionsBuilder
|
||||
/// </summary>
|
||||
/// <param name="dbConnection"></param>
|
||||
/// <param name="dbContextOptionsBuilder"></param>
|
||||
/// <returns></returns>
|
||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
|
||||
bool UseReadWriteSeparation();
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceConfigurationParams<TShardingDbContext> : IVirtualDataSourceConfigurationParams
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public interface IVirtualDataSourceManager
|
||||
{
|
||||
bool IsMultiShardingConfiguration { get; }
|
||||
ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; }
|
||||
IVirtualDataSource GetVirtualDataSource();
|
||||
List<IVirtualDataSource> GetAllVirtualDataSources();
|
||||
|
||||
/// <summary>
|
||||
/// 创建分片配置scope
|
||||
/// </summary>
|
||||
/// <param name="configId"></param>
|
||||
/// <returns></returns>
|
||||
VirtualDataSourceScope CreateScope(string configId);
|
||||
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
IVirtualDataSource<TShardingDbContext> GetVirtualDataSource();
|
||||
List<IVirtualDataSource<TShardingDbContext>> GetAllVirtualDataSources();
|
||||
void AddVirtualDataSource(IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
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);
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceRouteManager<TShardingDbContext> : IVirtualDataSourceRouteManager
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity:class;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common
|
||||
{
|
||||
public enum ShardingConfigurationStrategyEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回空
|
||||
/// </summary>
|
||||
ReturnNull = 1,
|
||||
/// <summary>
|
||||
/// 抛出异常
|
||||
/// </summary>
|
||||
ThrowIfNull = 1 << 1,
|
||||
/// <summary>
|
||||
/// 返回优先级最高的
|
||||
/// </summary>
|
||||
ReturnHighPriority = 1 << 2
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
|
@ -19,10 +22,18 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
public interface IVirtualDataSource
|
||||
{
|
||||
|
||||
string ConfigId { get; }
|
||||
int Priority { get; }
|
||||
IVirtualDataSourceConfigurationParams ConfigurationParams { get; }
|
||||
IConnectionStringManager ConnectionStringManager { get; }
|
||||
bool UseReadWriteSeparation { get; }
|
||||
/// <summary>
|
||||
/// 默认的数据源名称
|
||||
/// </summary>
|
||||
string DefaultDataSourceName { get; }
|
||||
string DefaultConnectionString { get;}
|
||||
IVirtualDataSourceRoute GetRoute(Type entityType);
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
/// </summary>
|
||||
|
@ -31,12 +42,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
/// <returns>data source names</returns>
|
||||
List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig);
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前数据源的路由
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IVirtualDataSourceRoute GetRoute(Type entityType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取默认的数据源信息
|
||||
/// </summary>
|
||||
|
@ -74,13 +79,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
/// <exception cref="ShardingCoreInvalidOperationException">重复添加默认数据源</exception>
|
||||
bool AddPhysicDataSource(IPhysicDataSource physicDataSource);
|
||||
|
||||
/// <summary>
|
||||
/// 添加分库路由
|
||||
/// </summary>
|
||||
/// <param name="virtualDataSourceRoute"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ShardingCoreInvalidOperationException">对象未配置分库</exception>
|
||||
bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
|
||||
/// <summary>
|
||||
/// 是否默认数据源
|
||||
/// </summary>
|
||||
|
@ -92,6 +90,22 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
/// </summary>
|
||||
/// <exception cref="ShardingCoreInvalidOperationException"></exception>
|
||||
void CheckVirtualDataSource();
|
||||
/// <summary>
|
||||
/// 如何根据connectionString 配置 DbContextOptionsBuilder
|
||||
/// </summary>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <param name="dbContextOptionsBuilder"></param>
|
||||
/// <returns></returns>
|
||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString, DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
/// <summary>
|
||||
/// 如何根据dbConnection 配置DbContextOptionsBuilder
|
||||
/// </summary>
|
||||
/// <param name="dbConnection"></param>
|
||||
/// <param name="dbContextOptionsBuilder"></param>
|
||||
/// <returns></returns>
|
||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
|
||||
IDictionary<string, string> GetDataSources();
|
||||
}
|
||||
/// <summary>
|
||||
/// 虚拟数据源 连接所有的实际数据源
|
||||
|
@ -99,5 +113,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
public interface IVirtualDataSource<TShardingDbContext> : IVirtualDataSource
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity:class;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
//using ShardingCore.Core.VirtualRoutes;
|
||||
//using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
//namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
//{
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Date: Saturday, 06 February 2021 14:24:01
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
// public interface IVirtualDataSourceManager
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 添加链接
|
||||
// /// </summary>
|
||||
// /// <param name="physicDataSource"></param>
|
||||
// bool AddPhysicDataSource(IPhysicDataSource physicDataSource);
|
||||
// IVirtualDataSource GetVirtualDataSource();
|
||||
// IPhysicDataSource GetDefaultDataSource();
|
||||
// string GetDefaultDataSourceName();
|
||||
// IPhysicDataSource GetPhysicDataSource(string dataSourceName);
|
||||
// }
|
||||
// public interface IVirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
|
||||
|
||||
|
||||
|
||||
// }
|
||||
//}
|
|
@ -30,5 +30,10 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
{
|
||||
return _physicDataSources.Keys.ToList();
|
||||
}
|
||||
|
||||
public IDictionary<string, string> GetDataSources()
|
||||
{
|
||||
return _physicDataSources.ToDictionary(k => k.Key, k => k.Value.ConnectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class SimpleVirtualDataSourceConfigurationParams<TShardingDbContext>: AbstractVirtualDataSourceConfigurationParams<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly ShardingGlobalConfigOptions _options;
|
||||
public override string ConfigId { get; }
|
||||
public override int Priority { get; }
|
||||
public override int MaxQueryConnectionsLimit { get; }
|
||||
public override ConnectionModeEnum ConnectionMode { get; }
|
||||
public override string DefaultDataSourceName { get; }
|
||||
public override string DefaultConnectionString { get; }
|
||||
public override IDictionary<string, string> ExtraDataSources { get; }
|
||||
public override IDictionary<string, IEnumerable<string>> ReadWriteSeparationConfigs { get; }
|
||||
public override ReadStrategyEnum? ReadStrategy { get; }
|
||||
public override bool? ReadWriteDefaultEnable { get; }
|
||||
public override int? ReadWriteDefaultPriority { get; }
|
||||
public override ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
public override IShardingComparer ShardingComparer { get; }
|
||||
|
||||
public SimpleVirtualDataSourceConfigurationParams(IServiceProvider serviceProvider,ShardingGlobalConfigOptions options)
|
||||
{
|
||||
_options = options;
|
||||
ConfigId = options.ConfigId;
|
||||
Priority = options.Priority;
|
||||
MaxQueryConnectionsLimit = options.MaxQueryConnectionsLimit;
|
||||
ConnectionMode = options.ConnectionMode;
|
||||
DefaultDataSourceName = options.DefaultDataSourceName;
|
||||
DefaultConnectionString = options.DefaultConnectionString;
|
||||
ExtraDataSources = options.DataSourcesConfigure?.Invoke(serviceProvider)??new ConcurrentDictionary<string, string>();
|
||||
ShardingComparer = options.ReplaceShardingComparerFactory?.Invoke(serviceProvider) ??
|
||||
new CSharpLanguageShardingComparer();
|
||||
if (options.ShardingReadWriteSeparationOptions != null)
|
||||
{
|
||||
ReadWriteSeparationConfigs = options.ShardingReadWriteSeparationOptions.ReadWriteSeparationConfigure?.Invoke(serviceProvider);
|
||||
ReadStrategy = options.ShardingReadWriteSeparationOptions.ReadStrategy;
|
||||
ReadWriteDefaultEnable = options.ShardingReadWriteSeparationOptions.DefaultEnable;
|
||||
ReadWriteDefaultPriority = options.ShardingReadWriteSeparationOptions.DefaultPriority;
|
||||
ReadConnStringGetStrategy = options.ShardingReadWriteSeparationOptions.ReadConnStringGetStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
_options.ConnectionStringConfigure.Invoke(connectionString, dbContextOptionsBuilder);
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
_options.ConnectionConfigure.Invoke(dbConnection, dbContextOptionsBuilder);
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.ShardingEnumerableQueries;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
|
@ -13,7 +15,9 @@ using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
|||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Utils;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
|
@ -26,26 +30,80 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
*/
|
||||
public class VirtualDataSource<TShardingDbContext> : IVirtualDataSource<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public IVirtualDataSourceConfigurationParams ConfigurationParams { get; }
|
||||
public IConnectionStringManager ConnectionStringManager { get; }
|
||||
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly ConcurrentDictionary<Type, IVirtualDataSourceRoute> _dataSourceVirtualRoutes = new ConcurrentDictionary<Type, IVirtualDataSourceRoute>();
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _dataSourceRouteManager;
|
||||
|
||||
private readonly IPhysicDataSourcePool _physicDataSourcePool;
|
||||
|
||||
public string ConfigId => ConfigurationParams.ConfigId;
|
||||
public int Priority => ConfigurationParams.Priority;
|
||||
public string DefaultDataSourceName { get; private set; }
|
||||
public string DefaultConnectionString { get; private set; }
|
||||
public bool UseReadWriteSeparation { get; }
|
||||
|
||||
public VirtualDataSource(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
public VirtualDataSource(IEntityMetadataManager<TShardingDbContext> entityMetadataManager, IVirtualDataSourceRouteManager<TShardingDbContext> dataSourceRouteManager, IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
ConfigurationParams = configurationParams;
|
||||
_physicDataSourcePool = new PhysicDataSourcePool();
|
||||
//Ìí¼ÓÊý¾ÝÔ´
|
||||
AddPhysicDataSource(new DefaultPhysicDataSource(ConfigurationParams.DefaultDataSourceName, ConfigurationParams.DefaultConnectionString, true));
|
||||
foreach (var extraDataSource in ConfigurationParams.ExtraDataSources)
|
||||
{
|
||||
AddPhysicDataSource(new DefaultPhysicDataSource(extraDataSource.Key, extraDataSource.Value, false));
|
||||
}
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_dataSourceRouteManager = dataSourceRouteManager;
|
||||
UseReadWriteSeparation = ConfigurationParams.UseReadWriteSeparation();
|
||||
if (UseReadWriteSeparation)
|
||||
{
|
||||
CheckReadWriteSeparation();
|
||||
ConnectionStringManager = new ReadWriteConnectionStringManager(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConnectionStringManager = new DefaultConnectionStringManager(this);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckReadWriteSeparation()
|
||||
{
|
||||
if (!ConfigurationParams.ReadStrategy.HasValue)
|
||||
{
|
||||
throw new ArgumentException(nameof(ConfigurationParams.ReadStrategy));
|
||||
}
|
||||
if (!ConfigurationParams.ReadConnStringGetStrategy.HasValue)
|
||||
{
|
||||
throw new ArgumentException(nameof(ConfigurationParams.ReadConnStringGetStrategy));
|
||||
}
|
||||
if (!ConfigurationParams.ReadWriteDefaultEnable.HasValue)
|
||||
{
|
||||
throw new ArgumentException(nameof(ConfigurationParams.ReadWriteDefaultEnable));
|
||||
}
|
||||
if (!ConfigurationParams.ReadWriteDefaultPriority.HasValue)
|
||||
{
|
||||
throw new ArgumentException(nameof(ConfigurationParams.ReadWriteDefaultPriority));
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> RouteTo(Type entityType,ShardingDataSourceRouteConfig routeRouteConfig)
|
||||
public IVirtualDataSourceRoute GetRoute(Type entityType)
|
||||
{
|
||||
return _dataSourceRouteManager.GetRoute(entityType);
|
||||
}
|
||||
|
||||
public IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity : class
|
||||
{
|
||||
return _dataSourceRouteManager.GetRoute<TEntity>();
|
||||
}
|
||||
|
||||
public List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig)
|
||||
{
|
||||
if (!_entityMetadataManager.IsShardingDataSource(entityType))
|
||||
return new List<string>(1) { DefaultDataSourceName };
|
||||
var virtualDataSourceRoute = GetRoute( entityType);
|
||||
var virtualDataSourceRoute = _dataSourceRouteManager.GetRoute(entityType);
|
||||
|
||||
if (routeRouteConfig.UseQueryable())
|
||||
return virtualDataSourceRoute.RouteWithPredicate(routeRouteConfig.GetQueryable(), true);
|
||||
|
@ -72,17 +130,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
throw new NotImplementedException(nameof(ShardingDataSourceRouteConfig));
|
||||
}
|
||||
|
||||
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>
|
||||
|
@ -101,7 +148,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
{
|
||||
Check.NotNull(dataSourceName, "data source name is null,plz confirm IShardingBootstrapper.Star()");
|
||||
var dataSource = _physicDataSourcePool.TryGet(dataSourceName);
|
||||
if (null== dataSource)
|
||||
if (null == dataSource)
|
||||
throw new ShardingCoreNotFoundException($"data source:[{dataSourceName}]");
|
||||
|
||||
return dataSource;
|
||||
|
@ -127,6 +174,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
return DefaultConnectionString;
|
||||
return GetPhysicDataSource(dataSourceName).ConnectionString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加数据源
|
||||
/// </summary>
|
||||
|
@ -148,19 +196,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
return _physicDataSourcePool.TryAdd(physicDataSource);
|
||||
}
|
||||
/// <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);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否是默认数据源
|
||||
/// </summary>
|
||||
/// <param name="dataSourceName"></param>
|
||||
|
@ -182,5 +217,26 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
throw new ShardingCoreInvalidOperationException(
|
||||
$"virtual data source not inited {nameof(DefaultConnectionString)} in IShardingDbContext null");
|
||||
}
|
||||
|
||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
var doUseDbContextOptionsBuilder = ConfigurationParams.UseDbContextOptionsBuilder(connectionString, dbContextOptionsBuilder);
|
||||
doUseDbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
return doUseDbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
var doUseDbContextOptionsBuilder = ConfigurationParams.UseDbContextOptionsBuilder(dbConnection, dbContextOptionsBuilder);
|
||||
doUseDbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
return doUseDbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public IDictionary<string, string> GetDataSources()
|
||||
{
|
||||
return _physicDataSourcePool.GetDataSources();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceAccessor: IVirtualDataSourceAccessor
|
||||
{
|
||||
private static AsyncLocal<VirtualDataSourceContext> _shardingConfigurationContext = new AsyncLocal<VirtualDataSourceContext>();
|
||||
|
||||
/// <summary>
|
||||
/// sharding route context use in using code block
|
||||
/// </summary>
|
||||
public VirtualDataSourceContext DataSourceContext
|
||||
{
|
||||
get => _shardingConfigurationContext.Value;
|
||||
set => _shardingConfigurationContext.Value = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceContext
|
||||
{
|
||||
public string ConfigId { get; }
|
||||
|
||||
public VirtualDataSourceContext(string configId)
|
||||
{
|
||||
ConfigId = configId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +1,140 @@
|
|||
//using System;
|
||||
//using System.Collections.Concurrent;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Linq;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
//using ShardingCore.Core.VirtualRoutes;
|
||||
//using ShardingCore.Sharding.Abstractions;
|
||||
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.ShardingConfigurations;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
//namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
//{
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Date: Saturday, 06 February 2021 15:24:08
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
// public class VirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
// private readonly IServiceProvider _serviceProvider;
|
||||
// /// <summary>
|
||||
// /// {sharding db context type :{entity type:virtual data source}}
|
||||
// /// </summary>
|
||||
// private readonly ConcurrentDictionary<Type, IVirtualDataSource> _virtualDataSources = new ConcurrentDictionary<Type, IVirtualDataSource>();
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IShardingConfigurationOptions<TShardingDbContext> _options;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _virtualDataSourceRouteManager;
|
||||
private readonly IVirtualDataSourceAccessor _virtualDataSourceAccessor;
|
||||
|
||||
private readonly ConcurrentDictionary<string, IVirtualDataSource> _virtualDataSources = new();
|
||||
|
||||
private string _defaultConfigId;
|
||||
private IVirtualDataSource _defaultVirtualDataSource;
|
||||
public VirtualDataSourceManager(IServiceProvider serviceProvider,IShardingConfigurationOptions<TShardingDbContext> options,IEntityMetadataManager<TShardingDbContext> entityMetadataManager,IVirtualDataSourceRouteManager<TShardingDbContext> virtualDataSourceRouteManager, IVirtualDataSourceAccessor virtualDataSourceAccessor)
|
||||
{
|
||||
|
||||
// public VirtualDataSourceManager(IServiceProvider serviceProvider)
|
||||
// {
|
||||
// _serviceProvider = serviceProvider;
|
||||
// //var shardingEntities = AssemblyHelper.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes())
|
||||
// // .Where(type => !String.IsNullOrEmpty(type.Namespace))
|
||||
// // .Where(type => !type.IsAbstract&&type.GetInterfaces()
|
||||
// // .Any(it => it.IsInterface &&typeof(IShardingDataSource)==it)
|
||||
// // );
|
||||
// //foreach (var shardingEntity in shardingEntities)
|
||||
// //{
|
||||
// // Type genericType = typeof(IVirtualDataSource<>);
|
||||
// // Type interfaceType = genericType.MakeGenericType(shardingEntity);
|
||||
// // var virtualDataSource = (IVirtualDataSource)serviceProvider.GetService(interfaceType);
|
||||
// // _virtualDataSources.TryAdd(virtualDataSource.EntityType, virtualDataSource);
|
||||
// //}
|
||||
// }
|
||||
_options = options;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
|
||||
var allShardingGlobalConfigOptions = options.GetAllShardingGlobalConfigOptions();
|
||||
if (allShardingGlobalConfigOptions.IsEmpty())
|
||||
throw new ArgumentException($"sharding virtual data source is empty");
|
||||
_virtualDataSourceAccessor = virtualDataSourceAccessor;
|
||||
if (options is ShardingMultiConfigurationOptions<TShardingDbContext> shardingMultiConfigurationOptions)
|
||||
{
|
||||
IsMultiShardingConfiguration = true;
|
||||
ShardingConfigurationStrategy = shardingMultiConfigurationOptions.ShardingConfigurationStrategy;
|
||||
}
|
||||
else if (options is ShardingSingleConfigurationOptions<TShardingDbContext> shardingSingleConfigurationOptions)
|
||||
{
|
||||
IsMultiShardingConfiguration = false;
|
||||
ShardingConfigurationStrategy = shardingSingleConfigurationOptions.ShardingConfigurationStrategy;
|
||||
}
|
||||
foreach (var shardingGlobalConfigOption in allShardingGlobalConfigOptions)
|
||||
{
|
||||
var simpleVirtualDataSourceConfigurationParams = new SimpleVirtualDataSourceConfigurationParams<TShardingDbContext>(serviceProvider,shardingGlobalConfigOption);
|
||||
var dataSource = new VirtualDataSource<TShardingDbContext>(_entityMetadataManager,_virtualDataSourceRouteManager, simpleVirtualDataSourceConfigurationParams);
|
||||
dataSource.CheckVirtualDataSource();
|
||||
if (!IsMultiShardingConfiguration)
|
||||
{
|
||||
if (_defaultVirtualDataSource != null || _defaultConfigId != null)
|
||||
throw new ShardingCoreInvalidOperationException("set sharding configuration error");
|
||||
_defaultVirtualDataSource = dataSource;
|
||||
_defaultConfigId = dataSource.ConfigId;
|
||||
}
|
||||
_virtualDataSources.TryAdd(dataSource.ConfigId, dataSource);
|
||||
}
|
||||
|
||||
// public bool AddPhysicDataSource(IPhysicDataSource physicDataSource)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
if (IsMultiShardingConfiguration)
|
||||
{
|
||||
var maxShardingConfiguration = _virtualDataSources.Values.OrderByDescending(o => o.Priority).FirstOrDefault();
|
||||
_defaultVirtualDataSource = maxShardingConfiguration;
|
||||
_defaultConfigId = maxShardingConfiguration.ConfigId;
|
||||
}
|
||||
}
|
||||
public bool IsMultiShardingConfiguration { get; }
|
||||
public ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; }
|
||||
public IVirtualDataSource GetVirtualDataSource()
|
||||
{
|
||||
if (!IsMultiShardingConfiguration)
|
||||
return _defaultVirtualDataSource;
|
||||
var configId = _virtualDataSourceAccessor.DataSourceContext?.ConfigId;
|
||||
if (!string.IsNullOrWhiteSpace(configId))
|
||||
{
|
||||
var hasValue = _virtualDataSources.TryGetValue(configId, out var virtualDataSource);
|
||||
if (hasValue)
|
||||
{
|
||||
return virtualDataSource;
|
||||
}
|
||||
}
|
||||
|
||||
// public IVirtualDataSource GetVirtualDataSource()
|
||||
// {
|
||||
// if (!_virtualDataSources.TryGetValue(shardingDbContextType, out var virtualDataSource))
|
||||
// throw new ShardingCoreInvalidOperationException($"not found virtual data source sharding db context type:[{shardingDbContextType.FullName}]");
|
||||
// return virtualDataSource;
|
||||
// }
|
||||
switch (ShardingConfigurationStrategy)
|
||||
{
|
||||
case ShardingConfigurationStrategyEnum.ReturnNull: return null;
|
||||
case ShardingConfigurationStrategyEnum.ReturnHighPriority: return _defaultVirtualDataSource;
|
||||
case ShardingConfigurationStrategyEnum.ThrowIfNull: throw new ShardingCoreNotFoundException($"no configuration,config id:[{configId}]");
|
||||
default:
|
||||
throw new ShardingCoreException(
|
||||
$"unknown {nameof(ShardingConfigurationStrategyEnum)}:[{ShardingConfigurationStrategy}]");
|
||||
}
|
||||
}
|
||||
|
||||
// public IPhysicDataSource GetDefaultDataSource()
|
||||
// {
|
||||
// var virtualDataSource = GetVirtualDataSource(shardingDbContextType);
|
||||
// return virtualDataSource.GetDefaultDataSource();
|
||||
// }
|
||||
List<IVirtualDataSource<TShardingDbContext>> IVirtualDataSourceManager<TShardingDbContext>.GetAllVirtualDataSources()
|
||||
{
|
||||
return GetAllVirtualDataSources().Select(o => (IVirtualDataSource<TShardingDbContext>)o).ToList();
|
||||
}
|
||||
|
||||
// public string GetDefaultDataSourceName()
|
||||
// {
|
||||
// var virtualDataSource = GetVirtualDataSource(shardingDbContextType);
|
||||
// return virtualDataSource.DefaultDataSourceName;
|
||||
// }
|
||||
public void AddVirtualDataSource(IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
{
|
||||
if (!IsMultiShardingConfiguration)
|
||||
throw new NotSupportedException("not support multi sharding configuration");
|
||||
var dataSource = new VirtualDataSource<TShardingDbContext>(_entityMetadataManager, _virtualDataSourceRouteManager, configurationParams);
|
||||
dataSource.CheckVirtualDataSource();
|
||||
if(_virtualDataSources.TryAdd(dataSource.ConfigId, dataSource))
|
||||
{
|
||||
if (IsMultiShardingConfiguration)
|
||||
{
|
||||
var maxShardingConfiguration = _virtualDataSources.Values.OrderByDescending(o => o.Priority).FirstOrDefault();
|
||||
_defaultVirtualDataSource = maxShardingConfiguration;
|
||||
_defaultConfigId = maxShardingConfiguration.ConfigId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public IPhysicDataSource GetPhysicDataSource(string dataSourceName)
|
||||
// {
|
||||
// throw new NotImplementedException();
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
IVirtualDataSource<TShardingDbContext> IVirtualDataSourceManager<TShardingDbContext>.GetVirtualDataSource()
|
||||
{
|
||||
return (IVirtualDataSource<TShardingDbContext>)GetVirtualDataSource();
|
||||
}
|
||||
|
||||
public List<IVirtualDataSource> GetAllVirtualDataSources()
|
||||
{
|
||||
if (!IsMultiShardingConfiguration)
|
||||
return new List<IVirtualDataSource>(1) { _defaultVirtualDataSource };
|
||||
return _virtualDataSources.Values.ToList();
|
||||
}
|
||||
|
||||
public VirtualDataSourceScope CreateScope(string configId)
|
||||
{
|
||||
var virtualDataSourceScope = new VirtualDataSourceScope(_virtualDataSourceAccessor);
|
||||
_virtualDataSourceAccessor.DataSourceContext = new VirtualDataSourceContext(configId);
|
||||
return virtualDataSourceScope;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
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<TShardingDbContext> : IVirtualDataSourceRouteManager<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly ConcurrentDictionary<Type, IVirtualDataSourceRoute> _dataSourceVirtualRoutes = new ConcurrentDictionary<Type, IVirtualDataSourceRoute>();
|
||||
|
||||
public VirtualDataSourceRouteManager(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceScope:IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 分片配置访问器
|
||||
/// </summary>
|
||||
public IVirtualDataSourceAccessor VirtualDataSourceAccessor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="virtualDataSourceAccessor"></param>
|
||||
public VirtualDataSourceScope(IVirtualDataSourceAccessor virtualDataSourceAccessor)
|
||||
{
|
||||
VirtualDataSourceAccessor = virtualDataSourceAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
VirtualDataSourceAccessor.DataSourceContext = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
{
|
||||
if (EnableRouteParseCompileCache.HasValue)
|
||||
return EnableRouteParseCompileCache.Value;
|
||||
return ShardingConfigOption.EnableDataSourceRouteCompileCache.GetValueOrDefault();
|
||||
return EntityConfigOptions.EnableDataSourceRouteCompileCache.GetValueOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.EntityShardingMetadatas;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
@ -19,7 +20,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
{
|
||||
public EntityMetadata EntityMetadata { get; private set; }
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
public IShardingConfigOption ShardingConfigOption { get; private set; }
|
||||
public IShardingEntityConfigOptions EntityConfigOptions { get; private set; }
|
||||
|
||||
|
||||
public void Initialize(EntityMetadata entityMetadata)
|
||||
|
@ -35,8 +36,8 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
paginationConfiguration.Configure(paginationBuilder);
|
||||
}
|
||||
|
||||
ShardingConfigOption =
|
||||
ShardingContainer.GetRequiredShardingConfigOption(entityMetadata.ShardingDbContextType);
|
||||
EntityConfigOptions =
|
||||
ShardingContainer.GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
|
||||
}
|
||||
public virtual IPaginationConfiguration<T> CreatePaginationConfiguration()
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
|
@ -19,15 +21,20 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
/// <typeparam name="T"></typeparam>
|
||||
public class DataSourceRouteRuleContext
|
||||
{
|
||||
public ISet<Type> QueryEntities { get; }
|
||||
public DataSourceRouteRuleContext(IQueryable queryable,Type dbContextType)
|
||||
public DataSourceRouteRuleContext(IQueryable queryable,IShardingDbContext shardingDbContext)
|
||||
{
|
||||
Queryable = queryable;
|
||||
QueryEntities = queryable.ParseQueryableEntities(dbContextType);
|
||||
ShardingDbContext = shardingDbContext;
|
||||
VirtualDataSource = shardingDbContext.GetVirtualDataSource();
|
||||
QueryEntities = queryable.ParseQueryableEntities(shardingDbContext.GetType());
|
||||
}
|
||||
public ISet<Type> QueryEntities { get; }
|
||||
/// <summary>
|
||||
/// 查询条件
|
||||
/// </summary>
|
||||
public IQueryable Queryable { get; }
|
||||
|
||||
public IShardingDbContext ShardingDbContext { get; }
|
||||
public IVirtualDataSource VirtualDataSource { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,20 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
*/
|
||||
public class DataSourceRouteRuleEngine<TShardingDbContext> : IDataSourceRouteRuleEngine<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
|
||||
public DataSourceRouteRuleEngine(IVirtualDataSource<TShardingDbContext> virtualDataSource,IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
public DataSourceRouteRuleEngine(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
{
|
||||
_virtualDataSource = virtualDataSource;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
public DataSourceRouteResult Route(DataSourceRouteRuleContext routeRuleContext)
|
||||
{
|
||||
var virtualDataSource = routeRuleContext.VirtualDataSource;
|
||||
var dataSourceMaps = new Dictionary<Type, ISet<string>>();
|
||||
var notShardingDataSourceEntityType = routeRuleContext.QueryEntities.FirstOrDefault(o => !_entityMetadataManager.IsShardingDataSource(o));
|
||||
//存在不分库的
|
||||
if (notShardingDataSourceEntityType != null)
|
||||
dataSourceMaps.Add(notShardingDataSourceEntityType, new HashSet<string>() { _virtualDataSource.DefaultDataSourceName });
|
||||
dataSourceMaps.Add(notShardingDataSourceEntityType, new HashSet<string>() { virtualDataSource.DefaultDataSourceName });
|
||||
|
||||
|
||||
//if (queryEntities.Count > 1)
|
||||
|
@ -46,7 +45,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
{
|
||||
continue;
|
||||
}
|
||||
var dataSourceConfigs = _virtualDataSource.RouteTo(queryEntity,new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
|
||||
var dataSourceConfigs = virtualDataSource.RouteTo(queryEntity,new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
|
||||
if (!dataSourceMaps.ContainsKey(queryEntity))
|
||||
{
|
||||
dataSourceMaps.Add(queryEntity, dataSourceConfigs.ToHashSet());
|
||||
|
|
|
@ -33,20 +33,22 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="shardingDbContext"></param>
|
||||
/// <returns></returns>
|
||||
public DataSourceRouteRuleContext CreateContext(IQueryable queryable)
|
||||
public DataSourceRouteRuleContext CreateContext(IQueryable queryable,IShardingDbContext shardingDbContext)
|
||||
{
|
||||
return new DataSourceRouteRuleContext(queryable,typeof(TShardingDbContext));
|
||||
return new DataSourceRouteRuleContext(queryable, shardingDbContext);
|
||||
}
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="shardingDbContext"></param>
|
||||
/// <returns></returns>
|
||||
public DataSourceRouteResult Route(IQueryable queryable)
|
||||
public DataSourceRouteResult Route(IQueryable queryable, IShardingDbContext shardingDbContext)
|
||||
{
|
||||
var ruleContext = CreateContext(queryable);
|
||||
var ruleContext = CreateContext(queryable, shardingDbContext);
|
||||
return _dataSourceRouteRuleEngine.Route(ruleContext);
|
||||
}
|
||||
/// <summary>
|
||||
|
|
|
@ -16,8 +16,8 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
*/
|
||||
public interface IDataSourceRouteRuleEngineFactory
|
||||
{
|
||||
DataSourceRouteRuleContext CreateContext(IQueryable queryable);
|
||||
DataSourceRouteResult Route(IQueryable queryable);
|
||||
DataSourceRouteRuleContext CreateContext(IQueryable queryable, IShardingDbContext shardingDbContext);
|
||||
DataSourceRouteResult Route(IQueryable queryable, IShardingDbContext shardingDbContext);
|
||||
DataSourceRouteResult Route(DataSourceRouteRuleContext ruleContext);
|
||||
}
|
||||
public interface IDataSourceRouteRuleEngineFactory<TShardingDbContext> : IDataSourceRouteRuleEngineFactory
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
if (EnableRouteParseCompileCache.HasValue)
|
||||
return EnableRouteParseCompileCache.Value;
|
||||
return ShardingConfigOption.EnableTableRouteCompileCache.GetValueOrDefault();
|
||||
return EntityConfigOptions.EnableTableRouteCompileCache.GetValueOrDefault();
|
||||
}
|
||||
/// <summary>
|
||||
/// 对表达式进行缓存编译默认永久缓存单个参数表达式,且不包含orElse只包含单个AndAlso或者没有AndAlso的,
|
||||
|
|
|
@ -5,6 +5,7 @@ using ShardingCore.Core.EntityMetadatas;
|
|||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
||||
|
@ -22,14 +23,15 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
public IShardingConfigOption ShardingConfigOption { get; private set; }
|
||||
public IShardingEntityConfigOptions EntityConfigOptions { get; private set; }
|
||||
public virtual void Initialize(EntityMetadata entityMetadata)
|
||||
{
|
||||
if (!_doOnlyOnce.IsUnDo())
|
||||
throw new ShardingCoreInvalidOperationException("already init");
|
||||
EntityMetadata = entityMetadata;
|
||||
ShardingConfigOption =
|
||||
ShardingContainer.GetRequiredShardingConfigOption(entityMetadata.ShardingDbContextType);
|
||||
|
||||
EntityConfigOptions =
|
||||
ShardingContainer.GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
}
|
||||
public virtual IPaginationConfiguration<T> CreatePaginationConfiguration()
|
||||
{
|
||||
|
|
|
@ -30,6 +30,8 @@ using ShardingCore.Sharding.ShardingQueryExecutors;
|
|||
using ShardingCore.TableCreator;
|
||||
using System;
|
||||
using ShardingCore.Core.QueryTrackers;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
|
@ -53,13 +55,11 @@ namespace ShardingCore
|
|||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="optionsAction"></param>
|
||||
/// <param name="contextLifetime"></param>
|
||||
/// <param name="optionsLifetime"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingDbContext<TShardingDbContext>(this IServiceCollection services,
|
||||
Action<string, DbContextOptionsBuilder> optionsAction = null,
|
||||
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
|
||||
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
|
@ -70,20 +70,20 @@ namespace ShardingCore
|
|||
throw new NotSupportedException($"{nameof(optionsLifetime)}:{nameof(ServiceLifetime.Singleton)}");
|
||||
Action<IServiceProvider, DbContextOptionsBuilder> shardingOptionAction = (sp, option) =>
|
||||
{
|
||||
var virtualDataSource = sp.GetRequiredService<IVirtualDataSource<TShardingDbContext>>();
|
||||
var virtualDataSource = sp.GetRequiredService<IVirtualDataSourceManager<TShardingDbContext>>().GetVirtualDataSource();
|
||||
var connectionString = virtualDataSource.GetConnectionString(virtualDataSource.DefaultDataSourceName);
|
||||
optionsAction?.Invoke(connectionString, option);
|
||||
virtualDataSource.ConfigurationParams.UseDbContextOptionsBuilder(connectionString, option);
|
||||
option.UseSharding<TShardingDbContext>();
|
||||
};
|
||||
services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
|
||||
return services.AddShardingConfigure<TShardingDbContext>(optionsAction);
|
||||
return services.AddShardingConfigure<TShardingDbContext>();
|
||||
}
|
||||
|
||||
public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingConfigure<TShardingDbContext>(this IServiceCollection services, Action<string, DbContextOptionsBuilder> queryConfigure)
|
||||
public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingConfigure<TShardingDbContext>(this IServiceCollection services)
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
ShardingCoreHelper.CheckContextConstructors<TShardingDbContext>();
|
||||
return new ShardingCoreConfigBuilder<TShardingDbContext>(services, queryConfigure);
|
||||
return new ShardingCoreConfigBuilder<TShardingDbContext>(services);
|
||||
}
|
||||
|
||||
internal static IServiceCollection AddInternalShardingCore(this IServiceCollection services)
|
||||
|
@ -98,10 +98,11 @@ namespace ShardingCore
|
|||
services.TryAddSingleton(typeof(IStreamMergeContextFactory<>), typeof(StreamMergeContextFactory<>));
|
||||
services.TryAddSingleton(typeof(IShardingTableCreator<>), typeof(ShardingTableCreator<>));
|
||||
//虚拟数据源管理
|
||||
services.TryAddSingleton(typeof(IVirtualDataSource<>), typeof(VirtualDataSource<>));
|
||||
services.TryAddSingleton(typeof(IVirtualDataSourceRouteManager<>), typeof(VirtualDataSourceRouteManager<>));
|
||||
services.TryAddSingleton(typeof(IDataSourceRouteRuleEngine<>), typeof(DataSourceRouteRuleEngine<>));
|
||||
services.TryAddSingleton(typeof(IDataSourceRouteRuleEngineFactory<>), typeof(DataSourceRouteRuleEngineFactory<>));
|
||||
|
||||
//读写分离链接创建工厂
|
||||
services.TryAddSingleton<IReadWriteConnectorFactory, ReadWriteConnectorFactory>();
|
||||
|
||||
//虚拟表管理
|
||||
services.TryAddSingleton(typeof(IVirtualTableManager<>), typeof(VirtualTableManager<>));
|
||||
|
@ -163,5 +164,29 @@ namespace ShardingCore
|
|||
.ReplaceService<IModelSource,ShardingModelSource>()
|
||||
.ReplaceService<IModelCustomizer, ShardingModelCustomizer<TShardingDbContext>>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//public static IServiceCollection AddSingleShardingDbContext<TShardingDbContext>(this IServiceCollection services, Action<ShardingGlobalConfigOptions> configure,
|
||||
// Action<string, DbContextOptionsBuilder> optionsAction = null,
|
||||
// ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
|
||||
// ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// if (contextLifetime == ServiceLifetime.Singleton)
|
||||
// throw new NotSupportedException($"{nameof(contextLifetime)}:{nameof(ServiceLifetime.Singleton)}");
|
||||
// if (optionsLifetime == ServiceLifetime.Singleton)
|
||||
// throw new NotSupportedException($"{nameof(optionsLifetime)}:{nameof(ServiceLifetime.Singleton)}");
|
||||
// Action<IServiceProvider, DbContextOptionsBuilder> shardingOptionAction = (sp, option) =>
|
||||
// {
|
||||
// var virtualDataSource = sp.GetRequiredService<IVirtualDataSourceManager<TShardingDbContext>>().GetVirtualDataSource();
|
||||
// var connectionString = virtualDataSource.GetConnectionString(virtualDataSource.DefaultDataSourceName);
|
||||
// optionsAction?.Invoke(connectionString, option);
|
||||
// option.UseSharding<TShardingDbContext>();
|
||||
// };
|
||||
// services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
|
||||
// return services.AddShardingConfigure<TShardingDbContext>(optionsAction);
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,9 @@ using System.Linq;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.ShardingConfigurations.ConfigBuilders;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
|
@ -24,17 +27,19 @@ namespace ShardingCore.DIExtensions
|
|||
|
||||
|
||||
public ShardingConfigOption<TShardingDbContext> ShardingConfigOption { get; }
|
||||
public List<ShardingGlobalConfigOptions> ShardingGlobalConfigOptions { get; }
|
||||
public ShardingEntityConfigOptions<TShardingDbContext> ShardingEntityConfigOptions { get; }
|
||||
|
||||
|
||||
|
||||
public ShardingCoreConfigBuilder(IServiceCollection services,Action<string,DbContextOptionsBuilder> queryConfigure)
|
||||
public ShardingCoreConfigBuilder(IServiceCollection services)
|
||||
{
|
||||
Services = services;
|
||||
ShardingConfigOption = new ShardingConfigOption<TShardingDbContext>();
|
||||
ShardingConfigOption.UseShardingQuery(queryConfigure);
|
||||
ShardingGlobalConfigOptions = new List<ShardingGlobalConfigOptions>();
|
||||
ShardingEntityConfigOptions = new ShardingEntityConfigOptions<TShardingDbContext>();
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("plz use AddEntityConfig")]
|
||||
public ShardingTransactionBuilder<TShardingDbContext> Begin(Action<ShardingCoreBeginOptions> shardingCoreBeginOptionsConfigure)
|
||||
{
|
||||
var shardingCoreBeginOptions = new ShardingCoreBeginOptions();
|
||||
|
@ -64,6 +69,12 @@ namespace ShardingCore.DIExtensions
|
|||
return new ShardingTransactionBuilder<TShardingDbContext>(this);
|
||||
//return new ShardingQueryBuilder<TShardingDbContext>(this);
|
||||
}
|
||||
|
||||
public ShardingEntityConfigBuilder<TShardingDbContext> AddEntityConfig(Action<ShardingEntityConfigOptions<TShardingDbContext>> entityConfigure)
|
||||
{
|
||||
entityConfigure?.Invoke(ShardingEntityConfigOptions);
|
||||
return new ShardingEntityConfigBuilder<TShardingDbContext>(this);
|
||||
}
|
||||
//public ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> AddDefaultDataSource(string dataSourceName, string connectionString)
|
||||
//{
|
||||
// if (!string.IsNullOrWhiteSpace(defaultDataSourceName) || !string.IsNullOrWhiteSpace(defaultConnectionString))
|
||||
|
@ -84,6 +95,14 @@ namespace ShardingCore.DIExtensions
|
|||
|
||||
public class ShardingCoreBeginOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
|
@ -114,7 +133,7 @@ namespace ShardingCore.DIExtensions
|
|||
public bool? EnableTableRouteCompileCache { get; set; }
|
||||
public bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
|
||||
private readonly ISet<Type> _createTableEntities = new HashSet<Type>();
|
||||
private readonly ISet<Type> _createTableEntities = new HashSet<Type>();
|
||||
|
||||
public void AddEntitiesTryCreateTable(params Type[] entityTypes)
|
||||
{
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace ShardingCore.DIExtensions
|
|||
/// </summary>
|
||||
/// <param name="newShardingComparerFactory"></param>
|
||||
/// <returns></returns>
|
||||
public ShardingCoreConfigEndBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
|
||||
public ShardingCoreConfigEndBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
|
||||
return this;
|
||||
|
@ -64,19 +64,19 @@ namespace ShardingCore.DIExtensions
|
|||
_shardingCoreConfigBuilder.ShardingConfigOption);
|
||||
|
||||
|
||||
//添加创建TActualDbContext 的DbContextOptionsBuilder创建者
|
||||
var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.SameConnectionConfigure,
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.DefaultQueryConfigure);
|
||||
services
|
||||
.AddSingleton<IShardingDbContextOptionsBuilderConfig<TShardingDbContext>,
|
||||
ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp => config);
|
||||
////添加创建TActualDbContext 的DbContextOptionsBuilder创建者
|
||||
//var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(
|
||||
// _shardingCoreConfigBuilder.ShardingConfigOption.SameConnectionConfigure,
|
||||
// _shardingCoreConfigBuilder.ShardingConfigOption.DefaultQueryConfigure);
|
||||
//services
|
||||
// .AddSingleton<IShardingDbContextOptionsBuilderConfig<TShardingDbContext>,
|
||||
// ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp => config);
|
||||
|
||||
if (_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparerFactory == null)
|
||||
{
|
||||
throw new ShardingCoreConfigException($"{nameof(_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparerFactory)} is null");
|
||||
}
|
||||
services.AddSingleton<IShardingComparer<TShardingDbContext>>(_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparerFactory);
|
||||
//services.AddSingleton<IShardingComparer>(_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparerFactory);
|
||||
if (_shardingCoreConfigBuilder.ShardingConfigOption.TableEnsureManagerFactory == null)
|
||||
{
|
||||
throw new ShardingCoreConfigException($"{nameof(_shardingCoreConfigBuilder.ShardingConfigOption.TableEnsureManagerFactory)} is null");
|
||||
|
@ -84,15 +84,15 @@ namespace ShardingCore.DIExtensions
|
|||
services.AddSingleton<ITableEnsureManager<TShardingDbContext>>(_shardingCoreConfigBuilder.ShardingConfigOption.TableEnsureManagerFactory);
|
||||
|
||||
|
||||
if (!UseReadWrite)
|
||||
{
|
||||
services.AddTransient<IConnectionStringManager<TShardingDbContext>, DefaultConnectionStringManager<TShardingDbContext>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
services.AddTransient<IConnectionStringManager<TShardingDbContext>, ReadWriteConnectionStringManager<TShardingDbContext>>();
|
||||
RegisterReadWriteConfigure(services);
|
||||
}
|
||||
//if (!UseReadWrite)
|
||||
//{
|
||||
// services.AddTransient<IConnectionStringManager<TShardingDbContext>, DefaultConnectionStringManager<TShardingDbContext>>();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// services.AddTransient<IConnectionStringManager<TShardingDbContext>, ReadWriteConnectionStringManager<TShardingDbContext>>();
|
||||
// RegisterReadWriteConfigure(services);
|
||||
//}
|
||||
services.AddInternalShardingCore();
|
||||
|
||||
return services;
|
||||
|
@ -105,27 +105,27 @@ namespace ShardingCore.DIExtensions
|
|||
/// <exception cref="ShardingCoreInvalidOperationException"></exception>
|
||||
private void RegisterReadWriteConfigure(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IReadWriteOptions<TShardingDbContext>, ReadWriteOptions<TShardingDbContext>>(sp =>
|
||||
new ReadWriteOptions<TShardingDbContext>(
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReadWriteDefaultPriority,
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReadWriteDefaultEnable,
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReadStrategyEnum,
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringGetStrategy));
|
||||
//services.AddSingleton<IReadWriteOptions<TShardingDbContext>, ReadWriteOptions<TShardingDbContext>>(sp =>
|
||||
// new ReadWriteOptions<TShardingDbContext>(
|
||||
// _shardingCoreConfigBuilder.ShardingConfigOption.ReadWriteDefaultPriority,
|
||||
// _shardingCoreConfigBuilder.ShardingConfigOption.ReadWriteDefaultEnable,
|
||||
// _shardingCoreConfigBuilder.ShardingConfigOption.ReadStrategyEnum,
|
||||
// _shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringGetStrategy));
|
||||
|
||||
services
|
||||
.AddSingleton<IShardingConnectionStringResolver<TShardingDbContext>,
|
||||
ReadWriteShardingConnectionStringResolver<TShardingDbContext>>(sp =>
|
||||
{
|
||||
var readWriteConnectorFactory = sp.GetRequiredService<IReadWriteConnectorFactory>();
|
||||
var readConnStrings = _shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringConfigure(sp);
|
||||
var readWriteLoopConnectors = readConnStrings.Select(o => readWriteConnectorFactory.CreateConnector<TShardingDbContext>(_shardingCoreConfigBuilder.ShardingConfigOption.ReadStrategyEnum,o.Key,o.Value));
|
||||
//services
|
||||
// .AddSingleton<IShardingConnectionStringResolver<TShardingDbContext>,
|
||||
// ReadWriteShardingConnectionStringResolver<TShardingDbContext>>(sp =>
|
||||
// {
|
||||
// var readWriteConnectorFactory = sp.GetRequiredService<IReadWriteConnectorFactory>();
|
||||
// var readConnStrings = _shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringConfigure(sp);
|
||||
// var readWriteLoopConnectors = readConnStrings.Select(o => readWriteConnectorFactory.CreateConnector<TShardingDbContext>(_shardingCoreConfigBuilder.ShardingConfigOption.ReadStrategyEnum,o.Key,o.Value));
|
||||
|
||||
return new ReadWriteShardingConnectionStringResolver<TShardingDbContext>(
|
||||
readWriteLoopConnectors);
|
||||
});
|
||||
// return new ReadWriteShardingConnectionStringResolver<TShardingDbContext>(
|
||||
// readWriteLoopConnectors);
|
||||
// });
|
||||
|
||||
services.TryAddSingleton<IShardingReadWriteManager, ShardingReadWriteManager>();
|
||||
services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
|
||||
services.TryAddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace ShardingCore.DIExtensions
|
|||
}
|
||||
return new ShardingReadWriteSeparationBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
|
||||
}
|
||||
public ShardingDataBaseOrTableBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
|
||||
public ShardingDataBaseOrTableBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
|
||||
return this;
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace ShardingCore.DIExtensions
|
|||
|
||||
return new ShardingTableBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
|
||||
}
|
||||
public ShardingDataSourceRouteBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
|
||||
public ShardingDataSourceRouteBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
|
||||
return this;
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace ShardingCore.DIExtensions
|
|||
_shardingCoreConfigBuilder.ShardingConfigOption.UseReadWriteConfiguration(readWriteSeparationConfigure,readStrategyEnum, defaultEnable,defaultPriority, readConnStringGetStrategy);
|
||||
return new ShardingCoreConfigEndBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
|
||||
}
|
||||
public ShardingReadWriteSeparationBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
|
||||
public ShardingReadWriteSeparationBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
|
||||
return this;
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ShardingCore.DIExtensions
|
|||
}
|
||||
return new ShardingReadWriteSeparationBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
|
||||
}
|
||||
public ShardingTableBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
|
||||
public ShardingTableBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
|
||||
return this;
|
||||
|
|
|
@ -1,85 +1,76 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Bootstrapers;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.TableCreator;
|
||||
using ShardingCore.TableExists;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace ShardingCore.DynamicDataSources
|
||||
{
|
||||
|
||||
public class DataSourceInitializer<TShardingDbContext> : IDataSourceInitializer<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _entityConfigOptions;
|
||||
private readonly IRouteTailFactory _routeTailFactory;
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IShardingTableCreator<TShardingDbContext> _tableCreator;
|
||||
private readonly ILogger<DataSourceInitializer<TShardingDbContext>> _logger;
|
||||
private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
|
||||
public DataSourceInitializer(IShardingConfigOption<TShardingDbContext> shardingConfigOption,
|
||||
public DataSourceInitializer(
|
||||
IShardingEntityConfigOptions<TShardingDbContext> entityConfigOptions,
|
||||
IRouteTailFactory routeTailFactory, IVirtualTableManager<TShardingDbContext> virtualTableManager,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
|
||||
IShardingTableCreator<TShardingDbContext> shardingTableCreator,
|
||||
IVirtualDataSource<TShardingDbContext> virtualDataSource,
|
||||
ILogger<DataSourceInitializer<TShardingDbContext>> logger)
|
||||
{
|
||||
_shardingConfigOption = shardingConfigOption;
|
||||
_entityConfigOptions = entityConfigOptions;
|
||||
_routeTailFactory = routeTailFactory;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_tableCreator = shardingTableCreator;
|
||||
_virtualDataSource = virtualDataSource;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void InitConfigure(string dataSourceName, string connectionString, bool isOnStart)
|
||||
public void InitConfigure(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName, string connectionString, bool isOnStart)
|
||||
{
|
||||
using (var serviceScope = ShardingContainer.ServiceProvider.CreateScope())
|
||||
{
|
||||
_virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(dataSourceName, connectionString, false));
|
||||
using var context = serviceScope.ServiceProvider.GetService<TShardingDbContext>();
|
||||
if (_shardingConfigOption.EnsureCreatedWithOutShardingTable||!isOnStart)
|
||||
EnsureCreated(context, dataSourceName);
|
||||
var tableEnsureManager = ShardingContainer.GetService<ITableEnsureManager<TShardingDbContext>>();
|
||||
//获取数据库存在的所有的表
|
||||
var existTables = tableEnsureManager?.GetExistTables(context, dataSourceName) ?? new HashSet<string>();
|
||||
if (_entityConfigOptions.EnsureCreatedWithOutShardingTable || !isOnStart)
|
||||
EnsureCreated(virtualDataSource, context, dataSourceName);
|
||||
//var tableEnsureManager = ShardingContainer.GetService<ITableEnsureManager<TShardingDbContext>>();
|
||||
////获取数据库存在的所有的表
|
||||
//var existTables = tableEnsureManager?.GetExistTables(context, dataSourceName) ?? new HashSet<string>();
|
||||
var existTables = new HashSet<string>();
|
||||
foreach (var entity in context.Model.GetEntityTypes())
|
||||
{
|
||||
var entityType = entity.ClrType;
|
||||
if (_virtualDataSource.IsDefault(dataSourceName))
|
||||
if (virtualDataSource.IsDefault(dataSourceName))
|
||||
{
|
||||
if (_entityMetadataManager.IsShardingTable(entityType))
|
||||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(entityType);
|
||||
//创建表
|
||||
CreateDataTable(dataSourceName, virtualTable, existTables,isOnStart);
|
||||
CreateDataTable( dataSourceName, virtualTable, existTables, isOnStart);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_entityMetadataManager.IsShardingDataSource(entityType))
|
||||
{
|
||||
var virtualDataSourceRoute = _virtualDataSource.GetRoute(entityType);
|
||||
var virtualDataSourceRoute = virtualDataSource.GetRoute(entityType);
|
||||
if (virtualDataSourceRoute.GetAllDataSourceNames().Contains(dataSourceName))
|
||||
{
|
||||
if (_entityMetadataManager.IsShardingTable(entityType))
|
||||
|
@ -91,11 +82,6 @@ namespace ShardingCore.DynamicDataSources
|
|||
}
|
||||
}
|
||||
}
|
||||
if (isOnStart&&_shardingConfigOption.NeedCreateTable(entityType))
|
||||
{
|
||||
if (!existTables.Contains(entity.GetEntityTypeTableName()))
|
||||
_tableCreator.CreateTable(dataSourceName, entityType, string.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +103,7 @@ namespace ShardingCore.DynamicDataSources
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!_shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
|
||||
if (!_entityConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||
{
|
||||
_logger.LogWarning(e,
|
||||
$"table :{virtualTable.GetVirtualTableName()}{entityMetadata.TableSeparator}{tail} will created.");
|
||||
|
@ -154,15 +140,15 @@ namespace ShardingCore.DynamicDataSources
|
|||
}
|
||||
}
|
||||
|
||||
return _shardingConfigOption.CreateShardingTableOnStart.GetValueOrDefault();
|
||||
return _entityConfigOptions.CreateShardingTableOnStart.GetValueOrDefault();
|
||||
}
|
||||
private void EnsureCreated(DbContext context, string dataSourceName)
|
||||
private void EnsureCreated(IVirtualDataSource<TShardingDbContext> virtualDataSource, DbContext context, string dataSourceName)
|
||||
{
|
||||
if (context is IShardingDbContext shardingDbContext)
|
||||
{
|
||||
var dbContext = shardingDbContext.GetDbContext(dataSourceName, false, _routeTailFactory.Create(string.Empty));
|
||||
|
||||
var isDefault = _virtualDataSource.IsDefault(dataSourceName);
|
||||
var isDefault = virtualDataSource.IsDefault(dataSourceName);
|
||||
|
||||
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@ namespace ShardingCore.DynamicDataSources
|
|||
throw new InvalidOperationException($"{nameof(DynamicDataSourceHelper)} create instance");
|
||||
}
|
||||
|
||||
public static void DynamicAppendDataSource<TShardingDbContext>(string dataSourceName, string connectionString) where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
var defaultDataSourceInitializer = ShardingContainer.GetService<IDataSourceInitializer<TShardingDbContext>>();
|
||||
defaultDataSourceInitializer.InitConfigure(dataSourceName, connectionString,false);
|
||||
}
|
||||
//public static void DynamicAppendDataSource<TShardingDbContext>(string dataSourceName, string connectionString) where TShardingDbContext:DbContext,IShardingDbContext
|
||||
//{
|
||||
// var defaultDataSourceInitializer = ShardingContainer.GetService<IDataSourceInitializer<TShardingDbContext>>();
|
||||
// defaultDataSourceInitializer.InitConfigure(dataSourceName, connectionString,false);
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.DynamicDataSources
|
||||
|
@ -13,9 +14,10 @@ namespace ShardingCore.DynamicDataSources
|
|||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="virtualDataSource"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <param name="isOnStart">当前是否是启动时被调用</param>
|
||||
void InitConfigure(string dataSourceName, string connectionString,bool isOnStart);
|
||||
void InitConfigure(IVirtualDataSource<TShardingDbContext> virtualDataSource,string dataSourceName, string connectionString,bool isOnStart);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,9 +53,7 @@ namespace ShardingCore.EFCores
|
|||
{
|
||||
if (null == _virtualDataSource)
|
||||
{
|
||||
_virtualDataSource =
|
||||
(IVirtualDataSource) ShardingContainer.GetService(
|
||||
typeof(IVirtualDataSource<>).GetGenericType0(_context.GetType()));
|
||||
_virtualDataSource = _context.GetVirtualDataSource();
|
||||
}
|
||||
|
||||
return _virtualDataSource;
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Extensions
|
||||
{
|
||||
public static class ShardingDbContextExtension
|
||||
{
|
||||
public static bool IsUseReadWriteSeparation(this IShardingDbContext shardingDbContext)
|
||||
{
|
||||
return shardingDbContext.GetVirtualDataSource().UseReadWriteSeparation;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -89,7 +89,7 @@ namespace ShardingCore.Extensions
|
|||
return new Dictionary<string, Dictionary<DbContext, IEnumerable<TEntity>>>();
|
||||
var entityType = typeof(TEntity);
|
||||
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
||||
var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService(typeof(IVirtualDataSource<>).GetGenericType0(shardingDbContext.GetType()));
|
||||
var virtualDataSource = shardingDbContext.GetVirtualDataSource();
|
||||
var entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContext.GetType()));
|
||||
var dataSourceNames = new Dictionary<string, Dictionary<string, BulkDicEntry<TEntity>>>();
|
||||
var entitiesArray = entities as TEntity[] ?? entities.ToArray();
|
||||
|
@ -245,7 +245,7 @@ namespace ShardingCore.Extensions
|
|||
public static IDictionary<string, IEnumerable<DbContext>> BulkShardingExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService(typeof(IVirtualDataSource<>).GetGenericType0(shardingDbContext.GetType()));
|
||||
var virtualDataSource = shardingDbContext.GetVirtualDataSource();
|
||||
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
||||
var virtualTableManager = (IVirtualTableManager)ShardingContainer.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContext.GetType()));
|
||||
var entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContext.GetType()));
|
||||
|
|
|
@ -85,9 +85,7 @@ namespace ShardingCore.Extensions
|
|||
if (shardingDbContext is ISupportShardingReadWrite shardingReadWrite)
|
||||
{
|
||||
var shardingDbContextType = shardingDbContext.GetType();
|
||||
var shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(shardingDbContextType);
|
||||
var useReadWrite=shardingConfigOption?.UseReadWrite ?? false;
|
||||
if (useReadWrite)
|
||||
if (shardingDbContext.IsUseReadWriteSeparation())
|
||||
{
|
||||
var shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>();
|
||||
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(shardingDbContextType);
|
||||
|
|
|
@ -38,10 +38,6 @@ namespace ShardingCore.Extensions
|
|||
return virtualDataSource.RouteTo(typeof(TEntity),
|
||||
new ShardingDataSourceRouteConfig(shardingKeyValue:shardingKeyValue))[0];
|
||||
}
|
||||
|
||||
public static IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>(this IVirtualDataSource virtualDataSource) where TEntity : class
|
||||
{
|
||||
return (IVirtualDataSourceRoute<TEntity>)virtualDataSource.GetRoute(typeof(TEntity));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
{
|
||||
|
@ -83,6 +84,11 @@ namespace ShardingCore.Sharding
|
|||
return ShardingDbContextExecutor.CreateGenericDbContext(entity);
|
||||
}
|
||||
|
||||
public IVirtualDataSource GetVirtualDataSource()
|
||||
{
|
||||
return ShardingDbContextExecutor.GetVirtualDataSource();
|
||||
}
|
||||
|
||||
|
||||
public override EntityEntry Add(object entity)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IConnectionStringManager<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
|
||||
public interface IConnectionStringManager
|
||||
{
|
||||
string GetConnectionString(string dataSourceName);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using System;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
|
||||
namespace ShardingCore.Sharding.Abstractions
|
||||
{
|
||||
|
@ -29,6 +30,8 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
/// <returns></returns>
|
||||
DbContext CreateGenericDbContext<T>(T entity) where T : class;
|
||||
|
||||
IVirtualDataSource GetVirtualDataSource();
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Sharding.ShardingDbContextExecutors;
|
||||
|
||||
namespace ShardingCore.Sharding.Abstractions
|
||||
|
@ -52,6 +53,8 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
/// <returns></returns>
|
||||
DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class;
|
||||
|
||||
IVirtualDataSource GetVirtualDataSource();
|
||||
|
||||
|
||||
|
||||
Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
|
||||
|
|
|
@ -19,30 +19,26 @@ namespace ShardingCore.Sharding
|
|||
*/
|
||||
public class ActualConnectionStringManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IConnectionStringManager<TShardingDbContext> _connectionStringManager;
|
||||
private readonly IReadWriteOptions<TShardingDbContext> _readWriteOptions;
|
||||
private readonly bool _useReadWriteSeparation;
|
||||
private readonly IShardingReadWriteManager _shardingReadWriteManager;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
public int ReadWriteSeparationPriority { get; set; }
|
||||
public bool ReadWriteSeparation { get; set; }
|
||||
public ReadStrategyEnum ReadStrategy { get; set; }
|
||||
public ReadConnStringGetStrategyEnum ReadConnStringGetStrategy { get; set; }
|
||||
private string _cacheConnectionString;
|
||||
public ActualConnectionStringManager()
|
||||
public ActualConnectionStringManager(IVirtualDataSource<TShardingDbContext> virtualDataSource)
|
||||
{
|
||||
_virtualDataSource=ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
|
||||
_connectionStringManager = ShardingContainer.GetService<IConnectionStringManager<TShardingDbContext>>();
|
||||
_virtualDataSource=virtualDataSource;
|
||||
_shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>();
|
||||
_useReadWriteSeparation = _connectionStringManager is ReadWriteConnectionStringManager<TShardingDbContext>;
|
||||
_useReadWriteSeparation = virtualDataSource.ConnectionStringManager is ReadWriteConnectionStringManager;
|
||||
if (_useReadWriteSeparation)
|
||||
{
|
||||
_readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
|
||||
if (_readWriteOptions != null)
|
||||
{
|
||||
ReadWriteSeparationPriority = _readWriteOptions.ReadWritePriority;
|
||||
ReadWriteSeparation = _readWriteOptions.ReadWriteSupport;
|
||||
}
|
||||
ReadWriteSeparationPriority = virtualDataSource.ConfigurationParams.ReadWriteDefaultPriority.GetValueOrDefault();
|
||||
ReadWriteSeparation = virtualDataSource.ConfigurationParams.ReadWriteDefaultEnable.GetValueOrDefault();
|
||||
ReadStrategy = virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault();
|
||||
ReadConnStringGetStrategy = virtualDataSource.ConfigurationParams.ReadConnStringGetStrategy.GetValueOrDefault();
|
||||
}
|
||||
|
||||
}
|
||||
//public bool IsUseReadWriteSeparation()
|
||||
//{
|
||||
|
@ -54,7 +50,7 @@ namespace ShardingCore.Sharding
|
|||
return GetWriteConnectionString(dataSourceName);
|
||||
if (!_useReadWriteSeparation)
|
||||
{
|
||||
return _connectionStringManager.GetConnectionString(dataSourceName);
|
||||
return _virtualDataSource.ConnectionStringManager.GetConnectionString(dataSourceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -85,19 +81,19 @@ namespace ShardingCore.Sharding
|
|||
}
|
||||
private string GetReadWriteSeparationConnectString0(string dataSourceName)
|
||||
{
|
||||
if (_readWriteOptions.ReadConnStringGetStrategy == ReadConnStringGetStrategyEnum.LatestFirstTime)
|
||||
if (ReadConnStringGetStrategy == ReadConnStringGetStrategyEnum.LatestFirstTime)
|
||||
{
|
||||
if (_cacheConnectionString == null)
|
||||
_cacheConnectionString = _connectionStringManager.GetConnectionString(dataSourceName);
|
||||
_cacheConnectionString = _virtualDataSource.ConnectionStringManager.GetConnectionString(dataSourceName);
|
||||
return _cacheConnectionString;
|
||||
}
|
||||
else if (_readWriteOptions.ReadConnStringGetStrategy == ReadConnStringGetStrategyEnum.LatestEveryTime)
|
||||
else if (ReadConnStringGetStrategy == ReadConnStringGetStrategyEnum.LatestEveryTime)
|
||||
{
|
||||
return _connectionStringManager.GetConnectionString(dataSourceName);
|
||||
return _virtualDataSource.ConnectionStringManager.GetConnectionString(dataSourceName);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException($"ReadWriteConnectionStringManager:{_readWriteOptions.ReadConnStringGetStrategy}");
|
||||
throw new ShardingCoreInvalidOperationException($"ReadWriteConnectionStringManager ReadConnStringGetStrategy:{ReadConnStringGetStrategy}");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,17 +11,19 @@ namespace ShardingCore.Sharding
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DefaultConnectionStringManager<TShardingDbContext> : IConnectionStringManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class DefaultConnectionStringManager : IConnectionStringManager
|
||||
{
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private readonly IVirtualDataSource _virtualDataSource;
|
||||
|
||||
public DefaultConnectionStringManager(IVirtualDataSource<TShardingDbContext> virtualDataSource)
|
||||
public DefaultConnectionStringManager(IVirtualDataSource virtualDataSource)
|
||||
{
|
||||
_virtualDataSource = virtualDataSource;
|
||||
}
|
||||
public string GetConnectionString(string dataSourceName)
|
||||
{
|
||||
return _virtualDataSource.GetConnectionString(dataSourceName);
|
||||
if (_virtualDataSource.IsDefault(dataSourceName))
|
||||
return _virtualDataSource.DefaultConnectionString;
|
||||
return _virtualDataSource.GetPhysicDataSource(dataSourceName).ConnectionString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,14 +34,12 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
private readonly StreamMergeContext<TEntity> _streamMergeContext;
|
||||
private readonly IShardingPageManager _shardingPageManager;
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private EnumeratorStreamMergeEngineFactory(StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
_streamMergeContext = streamMergeContext;
|
||||
_shardingPageManager = ShardingContainer.GetService<IShardingPageManager>();
|
||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
|
||||
_virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
|
||||
_entityMetadataManager = ShardingContainer.GetService<IEntityMetadataManager<TShardingDbContext>>();
|
||||
}
|
||||
|
||||
|
@ -50,6 +48,10 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
return new EnumeratorStreamMergeEngineFactory<TShardingDbContext, TEntity>(streamMergeContext);
|
||||
}
|
||||
|
||||
public IVirtualDataSourceRoute GetRoute(Type entityType)
|
||||
{
|
||||
return _streamMergeContext.GetShardingDbContext().GetVirtualDataSource().GetRoute(entityType);
|
||||
}
|
||||
public IEnumeratorStreamMergeEngine<TEntity> GetMergeEngine()
|
||||
{
|
||||
if (_streamMergeContext.IsRouteNotMatch())
|
||||
|
@ -63,7 +65,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
}
|
||||
|
||||
//未开启系统分表或者本次查询涉及多张分表
|
||||
if (_streamMergeContext.IsPaginationQuery() && _streamMergeContext.IsSupportPaginationQuery<TShardingDbContext,TEntity>() && _shardingPageManager.Current != null)
|
||||
if (_streamMergeContext.IsPaginationQuery() && _streamMergeContext.IsSupportPaginationQuery<TShardingDbContext, TEntity>() && _shardingPageManager.Current != null)
|
||||
{
|
||||
//获取虚拟表判断是否启用了分页配置
|
||||
var shardingEntityType = _streamMergeContext.QueryEntities.FirstOrDefault(o => _entityMetadataManager.IsShardingDataSource(o) || _entityMetadataManager.IsShardingTable(o));
|
||||
|
@ -100,7 +102,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
PaginationSequenceConfig tableSequenceOrderConfig = null;
|
||||
if (isShardingDataSource)
|
||||
{
|
||||
var virtualDataSourceRoute = _virtualDataSource.GetRoute(shardingEntityType);
|
||||
var virtualDataSourceRoute = GetRoute(shardingEntityType);
|
||||
if (virtualDataSourceRoute.EnablePagination)
|
||||
{
|
||||
dataSourceSequenceOrderConfig = virtualDataSourceRoute.PaginationMetadata.PaginationConfigs.OrderByDescending(o => o.AppendOrder)
|
||||
|
@ -146,7 +148,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
bool tableUseReverse = true;
|
||||
if (isShardingDataSource)
|
||||
{
|
||||
virtualDataSourceRoute = _virtualDataSource.GetRoute(shardingEntityType);
|
||||
virtualDataSourceRoute = GetRoute(shardingEntityType);
|
||||
if (virtualDataSourceRoute.EnablePagination)
|
||||
{
|
||||
dataSourceSequenceOrderConfig = orderCount == 1 ? GetPaginationFullMatch(virtualDataSourceRoute.PaginationMetadata.PaginationConfigs, primaryOrder) : GetPaginationPrimaryMatch(virtualDataSourceRoute.PaginationMetadata.PaginationConfigs, primaryOrder);
|
||||
|
@ -164,14 +166,14 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
|
||||
var useSequenceEnumeratorMergeEngine = isShardingDataSource && (dataSourceSequenceOrderConfig != null ||
|
||||
(isShardingTable &&
|
||||
!_streamMergeContext.IsCrossDataSource)) || (!isShardingDataSource&&isShardingTable && tableSequenceOrderConfig != null);
|
||||
!_streamMergeContext.IsCrossDataSource)) || (!isShardingDataSource && isShardingTable && tableSequenceOrderConfig != null);
|
||||
if (useSequenceEnumeratorMergeEngine)
|
||||
{
|
||||
return new SequenceEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity>(_streamMergeContext, dataSourceSequenceOrderConfig, tableSequenceOrderConfig, _shardingPageManager.Current.RouteQueryResults, primaryOrder.IsAsc);
|
||||
}
|
||||
|
||||
var total = _shardingPageManager.Current.RouteQueryResults.Sum(o => o.QueryResult);
|
||||
if (isShardingDataSource&& virtualDataSourceRoute.EnablePagination)
|
||||
if (isShardingDataSource && virtualDataSourceRoute.EnablePagination)
|
||||
{
|
||||
dataSourceUseReverse =
|
||||
EntityDataSourceUseReverseShardingPage(virtualDataSourceRoute, total);
|
||||
|
@ -181,7 +183,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
tableUseReverse =
|
||||
EntityTableReverseShardingPage(virtualTable, total);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//skip过大reserve skip
|
||||
if (dataSourceUseReverse && tableUseReverse)
|
||||
|
@ -196,7 +198,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
return null;
|
||||
}
|
||||
|
||||
private bool EntityDataSourceUseReverseShardingPage( IVirtualDataSourceRoute virtualDataSourceRoute,long total)
|
||||
private bool EntityDataSourceUseReverseShardingPage(IVirtualDataSourceRoute virtualDataSourceRoute, long total)
|
||||
{
|
||||
if (virtualDataSourceRoute.PaginationMetadata.EnableReverseShardingPage && _streamMergeContext.Take.GetValueOrDefault() > 0)
|
||||
{
|
||||
|
@ -207,7 +209,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines
|
|||
}
|
||||
return false;
|
||||
}
|
||||
private bool EntityTableReverseShardingPage( IVirtualTable virtualTable, long total)
|
||||
private bool EntityTableReverseShardingPage(IVirtualTable virtualTable, long total)
|
||||
{
|
||||
if (virtualTable.PaginationMetadata.EnableReverseShardingPage && _streamMergeContext.Take.GetValueOrDefault() > 0)
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations.Abstractions
|
|||
{
|
||||
public interface IReadWriteConnectorFactory
|
||||
{
|
||||
IReadWriteConnector CreateConnector<TShardingDbContext>(ReadStrategyEnum strategy, string dataSourceName, IEnumerable<string> connectionStrings) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
IReadWriteConnector CreateConnector(ReadStrategyEnum strategy, string dataSourceName,
|
||||
IEnumerable<string> connectionStrings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Text;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.ReadWriteConfigurations.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/7 11:13:52
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IReadWriteOptions<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认读写配置优先级
|
||||
/// </summary>
|
||||
int ReadWritePriority { get; }
|
||||
/// <summary>
|
||||
/// 默认是否开启读写分离
|
||||
/// </summary>
|
||||
bool ReadWriteSupport { get; }
|
||||
ReadStrategyEnum ReadStrategy { get; }
|
||||
ReadConnStringGetStrategyEnum ReadConnStringGetStrategy { get; }
|
||||
}
|
||||
}
|
||||
//namespace ShardingCore.Sharding.ReadWriteConfigurations.Abstractions
|
||||
//{
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Date: 2021/9/7 11:13:52
|
||||
// * @Ver: 1.0
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
// public interface IReadWriteOptions<TShardingDbContext>
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 默认读写配置优先级
|
||||
// /// </summary>
|
||||
// int ReadWritePriority { get; }
|
||||
// /// <summary>
|
||||
// /// 默认是否开启读写分离
|
||||
// /// </summary>
|
||||
// bool ReadWriteSupport { get; }
|
||||
// ReadStrategyEnum ReadStrategy { get; }
|
||||
// ReadConnStringGetStrategyEnum ReadConnStringGetStrategy { get; }
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -16,9 +16,7 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations.Abstractions
|
|||
/// <summary>
|
||||
/// 读写分离链接字符串解析
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
public interface IShardingConnectionStringResolver<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public interface IShardingConnectionStringResolver
|
||||
{
|
||||
bool ContainsReadWriteDataSourceName(string dataSourceName);
|
||||
string GetConnectionString(string dataSourceName);
|
||||
|
|
|
@ -16,16 +16,18 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ReadWriteConnectionStringManager<TShardingDbContext> : IConnectionStringManager<TShardingDbContext>, IReadWriteAppendConnectionString where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ReadWriteConnectionStringManager: IConnectionStringManager, IReadWriteAppendConnectionString
|
||||
{
|
||||
private IShardingConnectionStringResolver<TShardingDbContext> _shardingConnectionStringResolver;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
private IShardingConnectionStringResolver _shardingConnectionStringResolver;
|
||||
private readonly IVirtualDataSource _virtualDataSource;
|
||||
|
||||
|
||||
public ReadWriteConnectionStringManager(IShardingConnectionStringResolver<TShardingDbContext> shardingConnectionStringResolver,IVirtualDataSource<TShardingDbContext> virtualDataSource)
|
||||
public ReadWriteConnectionStringManager(IVirtualDataSource virtualDataSource)
|
||||
{
|
||||
_shardingConnectionStringResolver = shardingConnectionStringResolver;
|
||||
_virtualDataSource = virtualDataSource;
|
||||
var readWriteConnectorFactory = ShardingContainer.GetService<IReadWriteConnectorFactory>();
|
||||
var readWriteConnectors = virtualDataSource.ConfigurationParams.ReadWriteSeparationConfigs.Select(o=> readWriteConnectorFactory.CreateConnector(virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault(), o.Key,o.Value));
|
||||
_shardingConnectionStringResolver = new ReadWriteShardingConnectionStringResolver(readWriteConnectors, virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault());
|
||||
}
|
||||
public string GetConnectionString(string dataSourceName)
|
||||
{
|
||||
|
|
|
@ -12,25 +12,21 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
{
|
||||
public class ReadWriteConnectorFactory: IReadWriteConnectorFactory
|
||||
{
|
||||
public IReadWriteConnector CreateConnector<TShardingDbContext>(ReadStrategyEnum strategy,string dataSourceName, IEnumerable<string> connectionStrings) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public IReadWriteConnector CreateConnector(ReadStrategyEnum strategy,string dataSourceName, IEnumerable<string> connectionStrings)
|
||||
{
|
||||
var readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
|
||||
if (readWriteOptions == null)
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
"cant create read write connector should use read write");
|
||||
|
||||
if (readWriteOptions.ReadStrategy == ReadStrategyEnum.Loop)
|
||||
if (strategy == ReadStrategyEnum.Loop)
|
||||
{
|
||||
return new ReadWriteLoopConnector(dataSourceName, connectionStrings);
|
||||
}
|
||||
else if (readWriteOptions.ReadStrategy == ReadStrategyEnum.Random)
|
||||
else if (strategy == ReadStrategyEnum.Random)
|
||||
{
|
||||
return new ReadWriteRandomConnector(dataSourceName, connectionStrings);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"unknown read write strategy:[{readWriteOptions.ReadStrategy}]");
|
||||
$"unknown read write strategy:[{strategy}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
//using System;
|
||||
//using System.Collections.Generic;
|
||||
//using System.Text;
|
||||
//using Microsoft.EntityFrameworkCore;
|
||||
//using ShardingCore.Sharding.Abstractions;
|
||||
//using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.ReadWriteConfigurations
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/7 11:06:40
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
//namespace ShardingCore.Sharding.ReadWriteConfigurations
|
||||
//{
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Date: 2021/9/7 11:06:40
|
||||
// * @Ver: 1.0
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
|
||||
public class ReadWriteOptions<TShardingDbContext> : IReadWriteOptions<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public ReadWriteOptions(int readWritePriority, bool readWriteSupport, ReadStrategyEnum readStrategy, ReadConnStringGetStrategyEnum readConnStringGetStrategy)
|
||||
{
|
||||
ReadWritePriority = readWritePriority;
|
||||
ReadWriteSupport = readWriteSupport;
|
||||
ReadStrategy = readStrategy;
|
||||
ReadConnStringGetStrategy = readConnStringGetStrategy;
|
||||
}
|
||||
public Type ShardingDbContextType => typeof(TShardingDbContext);
|
||||
/// <summary>
|
||||
/// 默认读写配置优先级
|
||||
/// </summary>
|
||||
public int ReadWritePriority { get; }
|
||||
/// <summary>
|
||||
/// 默认是否开启读写分离
|
||||
/// </summary>
|
||||
public bool ReadWriteSupport { get; }
|
||||
// public class ReadWriteOptions<TShardingDbContext> : IReadWriteOptions<TShardingDbContext>
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
// public ReadWriteOptions(int readWritePriority, bool readWriteSupport, ReadStrategyEnum readStrategy, ReadConnStringGetStrategyEnum readConnStringGetStrategy)
|
||||
// {
|
||||
// ReadWritePriority = readWritePriority;
|
||||
// ReadWriteSupport = readWriteSupport;
|
||||
// ReadStrategy = readStrategy;
|
||||
// ReadConnStringGetStrategy = readConnStringGetStrategy;
|
||||
// }
|
||||
// public Type ShardingDbContextType => typeof(TShardingDbContext);
|
||||
// /// <summary>
|
||||
// /// 默认读写配置优先级
|
||||
// /// </summary>
|
||||
// public int ReadWritePriority { get; }
|
||||
// /// <summary>
|
||||
// /// 默认是否开启读写分离
|
||||
// /// </summary>
|
||||
// public bool ReadWriteSupport { get; }
|
||||
|
||||
public ReadStrategyEnum ReadStrategy { get; }
|
||||
public ReadConnStringGetStrategyEnum ReadConnStringGetStrategy { get; }
|
||||
}
|
||||
}
|
||||
// public ReadStrategyEnum ReadStrategy { get; }
|
||||
// public ReadConnStringGetStrategyEnum ReadConnStringGetStrategy { get; }
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -11,15 +11,17 @@ using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
|||
|
||||
namespace ShardingCore.Sharding.ReadWriteConfigurations
|
||||
{
|
||||
public class ReadWriteShardingConnectionStringResolver<TShardingDbContext> : IShardingConnectionStringResolver<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ReadWriteShardingConnectionStringResolver : IShardingConnectionStringResolver
|
||||
{
|
||||
private readonly ReadStrategyEnum _readStrategy;
|
||||
|
||||
private readonly ConcurrentDictionary<string, IReadWriteConnector> _connectors =
|
||||
new ConcurrentDictionary<string, IReadWriteConnector>();
|
||||
|
||||
private readonly IReadWriteOptions<TShardingDbContext> _readWriteOptions;
|
||||
private readonly IReadWriteConnectorFactory _readWriteConnectorFactory;
|
||||
public ReadWriteShardingConnectionStringResolver(IEnumerable<IReadWriteConnector> connectors)
|
||||
public ReadWriteShardingConnectionStringResolver(IEnumerable<IReadWriteConnector> connectors, ReadStrategyEnum readStrategy)
|
||||
{
|
||||
_readStrategy = readStrategy;
|
||||
var enumerator = connectors.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
|
@ -28,7 +30,6 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
_connectors.TryAdd(currentConnector.DataSourceName, currentConnector);
|
||||
}
|
||||
|
||||
_readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
|
||||
_readWriteConnectorFactory = ShardingContainer.GetService<IReadWriteConnectorFactory>();
|
||||
}
|
||||
|
||||
|
@ -48,7 +49,7 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
{
|
||||
if (!_connectors.TryGetValue(dataSourceName, out var connector))
|
||||
{
|
||||
connector = _readWriteConnectorFactory.CreateConnector<TShardingDbContext>(_readWriteOptions.ReadStrategy,
|
||||
connector = _readWriteConnectorFactory.CreateConnector(_readStrategy,
|
||||
dataSourceName, new List<string>()
|
||||
{
|
||||
connectionString
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
|
@ -31,12 +28,4 @@ namespace ShardingCore.Sharding.ShardingComparision.Abstractions
|
|||
/// <returns></returns>
|
||||
object CreateComparer(Type comparerType);
|
||||
}
|
||||
/// <summary>
|
||||
/// 泛型比较器用于依赖注入
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
public interface IShardingComparer<TShardingDbContext> : IShardingComparer where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -15,9 +15,9 @@ namespace ShardingCore.Sharding.ShardingComparision
|
|||
* @Date: Sunday, 31 October 2021 15:39:46
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class CSharpLanguageShardingComparer<TShardingDbContext> : IShardingComparer<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class CSharpLanguageShardingComparer : IShardingComparer
|
||||
{
|
||||
private readonly ConcurrentDictionary<Type, object> _comparers = new ConcurrentDictionary<Type, object>();
|
||||
private readonly ConcurrentDictionary<Type, object> _comparers = new ();
|
||||
public virtual int Compare(IComparable x, IComparable y, bool asc)
|
||||
{
|
||||
if (x is Guid xg && y is Guid yg)
|
||||
|
|
|
@ -61,13 +61,13 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
|
|||
public ShardingDbContextExecutor(DbContext shardingDbContext)
|
||||
{
|
||||
_shardingDbContext = shardingDbContext;
|
||||
_virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
|
||||
_virtualDataSource = ShardingContainer.GetRequiredVirtualDataSource<TShardingDbContext>();
|
||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
|
||||
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory<TShardingDbContext>>();
|
||||
_shardingDbContextOptionsBuilderConfig = ShardingContainer.GetService<IShardingDbContextOptionsBuilderConfig<TShardingDbContext>>();
|
||||
_entityMetadataManager = ShardingContainer.GetService<IEntityMetadataManager<TShardingDbContext>>();
|
||||
_routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
||||
_actualConnectionStringManager = new ActualConnectionStringManager<TShardingDbContext>();
|
||||
_actualConnectionStringManager = new ActualConnectionStringManager<TShardingDbContext>(_virtualDataSource);
|
||||
}
|
||||
|
||||
#region create db context
|
||||
|
@ -116,6 +116,11 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
|
|||
return CreateDbContext(false, dataSourceName, _routeTailFactory.Create(tail));
|
||||
}
|
||||
|
||||
public IVirtualDataSource GetVirtualDataSource()
|
||||
{
|
||||
return _virtualDataSource;
|
||||
}
|
||||
|
||||
private string GetDataSourceName<TEntity>(TEntity entity) where TEntity : class
|
||||
{
|
||||
if (!_entityMetadataManager.IsShardingDataSource(entity.GetType()))
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
{
|
||||
public class ShardingDbContextOptionsBuilderConfigure<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public ShardingDbContextOptionsBuilderConfigure(Action<DbConnection, DbContextOptionsBuilder> sameConnectionDbContextOptionsCreator, Action<string, DbContextOptionsBuilder> defaultQueryDbContextOptionsCreator)
|
||||
{
|
||||
SameConnectionDbContextOptionsCreator = sameConnectionDbContextOptionsCreator;
|
||||
DefaultQueryDbContextOptionsCreator = defaultQueryDbContextOptionsCreator;
|
||||
}
|
||||
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionDbContextOptionsCreator { get; }
|
||||
public Action<string, DbContextOptionsBuilder> DefaultQueryDbContextOptionsCreator { get; }
|
||||
|
||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
SameConnectionDbContextOptionsCreator(dbConnection, dbContextOptionsBuilder);
|
||||
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString, DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
DefaultQueryDbContextOptionsCreator(connectionString, dbContextOptionsBuilder);
|
||||
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore;
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Extensions;
|
||||
|
@ -24,7 +25,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
private readonly Expression _queryExpression;
|
||||
private readonly IEntityMetadataManager _entityMetadataManager;
|
||||
private readonly Type _shardingDbContextType;
|
||||
private readonly IShardingConfigOption _shardingConfigOption;
|
||||
private readonly IShardingEntityConfigOptions _entityConfigOptions;
|
||||
private QueryCompilerExecutor _queryCompilerExecutor;
|
||||
private bool? hasQueryCompilerExecutor;
|
||||
private bool? _isNoTracking;
|
||||
|
@ -39,10 +40,9 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
_queryExpression = queryExpression;
|
||||
_entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType));
|
||||
|
||||
_shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(_shardingDbContextType);
|
||||
_entityConfigOptions = ShardingContainer.GetRequiredShardingEntityConfigOption(_shardingDbContextType);
|
||||
//原生对象的原生查询如果是读写分离就需要启用并行查询
|
||||
_isParallelQuery =
|
||||
_shardingConfigOption.UseReadWrite && _shardingDbContext.CurrentIsReadWriteSeparation();
|
||||
_isParallelQuery = shardingDbContext.IsUseReadWriteSeparation() && _shardingDbContext.CurrentIsReadWriteSeparation();
|
||||
}
|
||||
|
||||
public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression)
|
||||
|
@ -103,8 +103,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
hasQueryCompilerExecutor = _queryEntities.All(o => !_entityMetadataManager.IsSharding(o));
|
||||
if (hasQueryCompilerExecutor.Value)
|
||||
{
|
||||
var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService(
|
||||
typeof(IVirtualDataSource<>).GetGenericType0(_shardingDbContextType));
|
||||
var virtualDataSource = _shardingDbContext.GetVirtualDataSource();
|
||||
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
||||
var dbContext = _shardingDbContext.GetDbContext(virtualDataSource.DefaultDataSourceName, IsParallelQuery(), routeTailFactory.Create(string.Empty));
|
||||
_queryCompilerExecutor = new QueryCompilerExecutor(dbContext, _queryExpression);
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
var dataSourceRouteRuleEngineFactory = (IDataSourceRouteRuleEngineFactory)ShardingContainer.GetService(typeof(IDataSourceRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
|
||||
var tableRouteRuleEngineFactory = (ITableRouteRuleEngineFactory)ShardingContainer.GetService(typeof(ITableRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
|
||||
var queryCombineResult = queryableCombine.Combine(queryCompilerContext);
|
||||
var dataSourceRouteResult = dataSourceRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable());
|
||||
var dataSourceRouteResult = dataSourceRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable(),shardingDbContext);
|
||||
var tableRouteResults = tableRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable());
|
||||
var routeResults = tableRouteResults as TableRouteResult[] ?? tableRouteResults.ToArray();
|
||||
var mergeCombineCompilerContext = MergeQueryCompilerContext.Create(queryCompilerContext, queryCombineResult, dataSourceRouteResult,
|
||||
|
|
|
@ -17,6 +17,7 @@ using System.Collections.Concurrent;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Exceptions;
|
||||
|
||||
|
||||
|
@ -65,11 +66,10 @@ namespace ShardingCore.Sharding
|
|||
public bool IsCrossTable { get; }
|
||||
|
||||
private readonly ITrackerManager _trackerManager;
|
||||
private readonly IShardingConfigOption _shardingConfigOption;
|
||||
private readonly IShardingEntityConfigOptions _shardingEntityConfigOptions;
|
||||
|
||||
private readonly ConcurrentDictionary<DbContext, object> _parallelDbContexts;
|
||||
|
||||
private readonly IShardingComparer _shardingComparer;
|
||||
|
||||
public StreamMergeContext(IMergeQueryCompilerContext mergeQueryCompilerContext,
|
||||
IRouteTailFactory routeTailFactory)
|
||||
|
@ -94,9 +94,8 @@ namespace ShardingCore.Sharding
|
|||
_trackerManager =
|
||||
(ITrackerManager)ShardingContainer.GetService(
|
||||
typeof(ITrackerManager<>).GetGenericType0(mergeQueryCompilerContext.GetShardingDbContextType()));
|
||||
_shardingComparer = (IShardingComparer)ShardingContainer.GetService(typeof(IShardingComparer<>).GetGenericType0(_shardingDbContext.GetType()));
|
||||
|
||||
_shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(mergeQueryCompilerContext.GetShardingDbContextType());
|
||||
_shardingEntityConfigOptions = ShardingContainer.GetRequiredShardingEntityConfigOption(mergeQueryCompilerContext.GetShardingDbContextType());
|
||||
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>();
|
||||
}
|
||||
public void ReSetOrders(IEnumerable<PropertyOrder> orders)
|
||||
|
@ -197,7 +196,7 @@ namespace ShardingCore.Sharding
|
|||
|
||||
public int GetMaxQueryConnectionsLimit()
|
||||
{
|
||||
return _shardingConfigOption.MaxQueryConnectionsLimit;
|
||||
return _shardingDbContext.GetVirtualDataSource().ConfigurationParams.MaxQueryConnectionsLimit;
|
||||
}
|
||||
public ConnectionModeEnum GetConnectionMode(int sqlCount)
|
||||
{
|
||||
|
@ -206,13 +205,13 @@ namespace ShardingCore.Sharding
|
|||
|
||||
private ConnectionModeEnum CalcConnectionMode(int sqlCount)
|
||||
{
|
||||
switch (_shardingConfigOption.ConnectionMode)
|
||||
switch (_shardingDbContext.GetVirtualDataSource().ConfigurationParams.ConnectionMode)
|
||||
{
|
||||
case ConnectionModeEnum.MEMORY_STRICTLY:
|
||||
case ConnectionModeEnum.CONNECTION_STRICTLY: return _shardingConfigOption.ConnectionMode;
|
||||
case ConnectionModeEnum.CONNECTION_STRICTLY: return _shardingDbContext.GetVirtualDataSource().ConfigurationParams.ConnectionMode;
|
||||
default:
|
||||
{
|
||||
return _shardingConfigOption.MaxQueryConnectionsLimit < sqlCount
|
||||
return _shardingDbContext.GetVirtualDataSource().ConfigurationParams.MaxQueryConnectionsLimit < sqlCount
|
||||
? ConnectionModeEnum.CONNECTION_STRICTLY
|
||||
: ConnectionModeEnum.MEMORY_STRICTLY; ;
|
||||
}
|
||||
|
@ -224,7 +223,7 @@ namespace ShardingCore.Sharding
|
|||
/// <returns></returns>
|
||||
private bool IsUseReadWriteSeparation()
|
||||
{
|
||||
return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation();
|
||||
return _shardingDbContext.IsUseReadWriteSeparation()&&_shardingDbContext.CurrentIsReadWriteSeparation();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -253,7 +252,7 @@ namespace ShardingCore.Sharding
|
|||
|
||||
public IShardingComparer GetShardingComparer()
|
||||
{
|
||||
return _shardingComparer;
|
||||
return _shardingDbContext.GetVirtualDataSource().ConfigurationParams.ShardingComparer;
|
||||
}
|
||||
|
||||
public TResult PreperExecute<TResult>(Func<TResult> emptyFunc)
|
||||
|
@ -296,7 +295,7 @@ namespace ShardingCore.Sharding
|
|||
|
||||
private bool ThrowIfQueryRouteNotMatch()
|
||||
{
|
||||
return _shardingConfigOption.ThrowIfQueryRouteNotMatch;
|
||||
return _shardingEntityConfigOptions.ThrowIfQueryRouteNotMatch;
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
@ -35,14 +35,8 @@ namespace ShardingCore
|
|||
public readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
|
||||
|
||||
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionConfigure { get; private set; }
|
||||
public Action<string, DbContextOptionsBuilder> DefaultQueryConfigure { get; private set; }
|
||||
|
||||
public Func<IServiceProvider, IDictionary<string, string>> DataSourcesConfigure { get; private set; }
|
||||
|
||||
public void UseShardingQuery(Action<string, DbContextOptionsBuilder> queryConfigure)
|
||||
{
|
||||
DefaultQueryConfigure = queryConfigure ?? throw new ArgumentNullException(nameof(queryConfigure));
|
||||
}
|
||||
public void UseShardingTransaction(Action<DbConnection, DbContextOptionsBuilder> transactionConfigure)
|
||||
{
|
||||
SameConnectionConfigure = transactionConfigure ?? throw new ArgumentNullException(nameof(transactionConfigure));
|
||||
|
@ -53,13 +47,13 @@ namespace ShardingCore
|
|||
DataSourcesConfigure = dataSourcesConfigure ?? throw new ArgumentNullException(nameof(dataSourcesConfigure));
|
||||
}
|
||||
|
||||
public Func<IServiceProvider, IShardingComparer<TShardingDbContext>> ReplaceShardingComparerFactory { get; private set; } = sp => new CSharpLanguageShardingComparer<TShardingDbContext>();
|
||||
public Func<IServiceProvider, IShardingComparer> ReplaceShardingComparerFactory { get; private set; } = sp => new CSharpLanguageShardingComparer();
|
||||
/// <summary>
|
||||
/// 替换默认的比较器
|
||||
/// </summary>
|
||||
/// <param name="newShardingComparerFactory"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
|
||||
public void ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
{
|
||||
ReplaceShardingComparerFactory=newShardingComparerFactory ?? throw new ArgumentNullException(nameof(newShardingComparerFactory));
|
||||
}
|
||||
|
@ -79,8 +73,8 @@ namespace ShardingCore
|
|||
|
||||
//public void UseShardingOptionsBuilder(Action<DbConnection, DbContextOptionsBuilder> sameConnectionConfigure, Action<string,DbContextOptionsBuilder> defaultQueryConfigure = null)
|
||||
//{
|
||||
// SameConnectionConfigure = sameConnectionConfigure ?? throw new ArgumentNullException(nameof(sameConnectionConfigure));
|
||||
// DefaultQueryConfigure = defaultQueryConfigure ?? throw new ArgumentNullException(nameof(defaultQueryConfigure));
|
||||
// ConnectionConfigure = sameConnectionConfigure ?? throw new ArgumentNullException(nameof(sameConnectionConfigure));
|
||||
// ConnectionStringConfigure = defaultQueryConfigure ?? throw new ArgumentNullException(nameof(defaultQueryConfigure));
|
||||
//}
|
||||
|
||||
public bool UseReadWrite => ReadConnStringConfigure != null;
|
||||
|
|
|
@ -7,6 +7,9 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
|
@ -108,14 +111,42 @@ namespace ShardingCore
|
|||
return Activator.CreateInstance(serviceType, @params);
|
||||
}
|
||||
|
||||
public static IShardingConfigOption<TShardingDbContext> GetRequiredShardingConfigOption<TShardingDbContext>()
|
||||
//public static IShardingConfigOption<TShardingDbContext> GetRequiredShardingConfigOption<TShardingDbContext>()
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// return (IShardingConfigOption<TShardingDbContext>)GetRequiredShardingConfigOption(typeof(TShardingDbContext));
|
||||
//}
|
||||
//public static IShardingConfigOption GetRequiredShardingConfigOption(Type shardingDbContextType)
|
||||
//{
|
||||
// return (IShardingConfigOption)ServiceProvider.GetService(typeof(IShardingConfigOption<>).GetGenericType0(shardingDbContextType));
|
||||
//}
|
||||
public static IShardingEntityConfigOptions<TShardingDbContext> GetRequiredShardingEntityConfigOption<TShardingDbContext>()
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return (IShardingConfigOption<TShardingDbContext>)GetRequiredShardingConfigOption(typeof(TShardingDbContext));
|
||||
return (IShardingEntityConfigOptions<TShardingDbContext>)GetRequiredShardingEntityConfigOption(typeof(TShardingDbContext));
|
||||
}
|
||||
public static IShardingConfigOption GetRequiredShardingConfigOption(Type shardingDbContextType)
|
||||
public static IShardingEntityConfigOptions GetRequiredShardingEntityConfigOption(Type shardingDbContextType)
|
||||
{
|
||||
return (IShardingConfigOption)ServiceProvider.GetService(typeof(IShardingConfigOption<>).GetGenericType0(shardingDbContextType));
|
||||
return (IShardingEntityConfigOptions)ServiceProvider.GetService(typeof(IShardingEntityConfigOptions<>).GetGenericType0(shardingDbContextType));
|
||||
}
|
||||
|
||||
public static IVirtualDataSourceManager<TShardingDbContext> GetRequiredVirtualDataSourceManager<TShardingDbContext>()
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return (IVirtualDataSourceManager<TShardingDbContext>)GetRequiredVirtualDataSourceManager(typeof(TShardingDbContext));
|
||||
}
|
||||
public static IVirtualDataSourceManager GetRequiredVirtualDataSourceManager(Type shardingDbContextType)
|
||||
{
|
||||
return (IVirtualDataSourceManager)ServiceProvider.GetService(typeof(IVirtualDataSourceManager<>).GetGenericType0(shardingDbContextType));
|
||||
}
|
||||
public static IVirtualDataSource<TShardingDbContext> GetRequiredVirtualDataSource<TShardingDbContext>()
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return GetRequiredVirtualDataSourceManager<TShardingDbContext>().GetVirtualDataSource();
|
||||
}
|
||||
public static IVirtualDataSource GetRequiredVirtualDataSource(Type shardingDbContextType)
|
||||
{
|
||||
return GetRequiredVirtualDataSourceManager(shardingDbContextType).GetVirtualDataSource();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
|
@ -28,14 +29,14 @@ namespace ShardingCore.TableCreator
|
|||
{
|
||||
private readonly ILogger<ShardingTableCreator<TShardingDbContext>> _logger;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _entityConfigOptions;
|
||||
private readonly IRouteTailFactory _routeTailFactory;
|
||||
|
||||
public ShardingTableCreator(ILogger<ShardingTableCreator<TShardingDbContext>> logger, IServiceProvider serviceProvider, IShardingConfigOption<TShardingDbContext> shardingConfigOption, IRouteTailFactory routeTailFactory)
|
||||
public ShardingTableCreator(ILogger<ShardingTableCreator<TShardingDbContext>> logger, IServiceProvider serviceProvider, IShardingEntityConfigOptions<TShardingDbContext> entityConfigOptions, IRouteTailFactory routeTailFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_serviceProvider = serviceProvider;
|
||||
_shardingConfigOption = shardingConfigOption;
|
||||
_entityConfigOptions = entityConfigOptions;
|
||||
_routeTailFactory = routeTailFactory;
|
||||
}
|
||||
|
||||
|
@ -77,7 +78,7 @@ namespace ShardingCore.TableCreator
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!_shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
|
||||
if (!_entityConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||
{
|
||||
_logger.LogWarning(ex,
|
||||
$"create table error entity name:[{shardingEntityType.Name}].");
|
||||
|
|
|
@ -9,6 +9,7 @@ using Microsoft.Extensions.Logging;
|
|||
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.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
|
@ -64,38 +65,42 @@ namespace ShardingCore.VirtualRoutes.Abstractions
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
var entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(EntityMetadata.ShardingDbContextType));
|
||||
var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService(typeof(IVirtualDataSource<>).GetGenericType0(EntityMetadata.ShardingDbContextType));
|
||||
var tableCreator = (IShardingTableCreator)ShardingContainer.GetService(typeof(IShardingTableCreator<>).GetGenericType0(EntityMetadata.ShardingDbContextType));
|
||||
var virtualDataSourceManager = (IVirtualDataSourceManager)ShardingContainer.GetService(typeof(IVirtualDataSourceManager<>).GetGenericType0(EntityMetadata.ShardingDbContextType));
|
||||
var allVirtualDataSources = virtualDataSourceManager.GetAllVirtualDataSources();
|
||||
var now = DateTime.Now.AddMinutes(IncrementMinutes);
|
||||
var tail = virtualTable.GetVirtualRoute().ShardingKeyToTail(now);
|
||||
ISet<string> dataSources = new HashSet<string>();
|
||||
if (entityMetadataManager.IsShardingDataSource(typeof(TEntity)))
|
||||
foreach (var virtualDataSource in allVirtualDataSources)
|
||||
{
|
||||
var virtualDataSourceRoute = virtualDataSource.GetRoute(typeof(TEntity));
|
||||
foreach (var dataSourceName in virtualDataSourceRoute.GetAllDataSourceNames())
|
||||
ISet<string> dataSources = new HashSet<string>();
|
||||
if (entityMetadataManager.IsShardingDataSource(typeof(TEntity)))
|
||||
{
|
||||
dataSources.Add(dataSourceName);
|
||||
var virtualDataSourceRoute = virtualDataSource.GetRoute(typeof(TEntity));
|
||||
foreach (var dataSourceName in virtualDataSourceRoute.GetAllDataSourceNames())
|
||||
{
|
||||
dataSources.Add(dataSourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSources.Add(virtualDataSource.DefaultDataSourceName);
|
||||
}
|
||||
_logger.LogInformation($"auto create table data source names:[{string.Join(",", dataSources)}]");
|
||||
foreach (var dataSource in dataSources)
|
||||
{
|
||||
try
|
||||
else
|
||||
{
|
||||
_logger.LogInformation($"begin table tail:[{tail}],entity:[{typeof(TEntity).Name}]");
|
||||
tableCreator.CreateTable(dataSource, typeof(TEntity), tail);
|
||||
_logger.LogInformation($"succeed table tail:[{tail}],entity:[{typeof(TEntity).Name}]");
|
||||
dataSources.Add(virtualDataSource.DefaultDataSourceName);
|
||||
}
|
||||
catch (Exception e)
|
||||
_logger.LogInformation($"auto create table data source names:[{string.Join(",", dataSources)}]");
|
||||
foreach (var dataSource in dataSources)
|
||||
{
|
||||
//ignore
|
||||
_logger.LogInformation($"warning table tail:[{tail}],entity:[{typeof(TEntity).Name}]");
|
||||
if (DoLogError)
|
||||
_logger.LogError(e, $"{dataSource} {typeof(TEntity).Name}'s create table error ");
|
||||
try
|
||||
{
|
||||
_logger.LogInformation($"begin table tail:[{tail}],entity:[{typeof(TEntity).Name}]");
|
||||
tableCreator.CreateTable(dataSource, typeof(TEntity), tail);
|
||||
_logger.LogInformation($"succeed table tail:[{tail}],entity:[{typeof(TEntity).Name}]");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//ignore
|
||||
_logger.LogInformation($"warning table tail:[{tail}],entity:[{typeof(TEntity).Name}]");
|
||||
if (DoLogError)
|
||||
_logger.LogError(e, $"{dataSource} {typeof(TEntity).Name}'s create table error ");
|
||||
}
|
||||
}
|
||||
}
|
||||
virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, tail));
|
||||
|
|
Loading…
Reference in New Issue