重构代码
This commit is contained in:
parent
efb785a005
commit
cc2d7e72b1
|
@ -89,6 +89,19 @@ namespace Sample.MySql
|
|||
}
|
||||
|
||||
app.UseShardingCore();
|
||||
|
||||
|
||||
using (var serviceScope = app.ApplicationServices.CreateScope())
|
||||
{
|
||||
var defaultShardingDbContext = serviceScope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
||||
}
|
||||
|
||||
Console.WriteLine("------------------");
|
||||
using (var serviceScope = app.ApplicationServices.CreateScope())
|
||||
{
|
||||
var defaultShardingDbContext = serviceScope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
||||
}
|
||||
Console.WriteLine("------------------");
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
|
|
@ -142,6 +142,8 @@ namespace Sample.SqlServer
|
|||
app.UseShardingCore();
|
||||
startNew.Stop();
|
||||
Console.WriteLine($"UseShardingCore:" + startNew.ElapsedMilliseconds + "ms");
|
||||
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 分表、分库对象确定参数用来初始化<see cref="EntityMetadata"/>时所需的信息
|
||||
/// </summary>
|
||||
public class EntityMetadataEnsureParams
|
||||
{
|
||||
public EntityMetadataEnsureParams(IEntityType entityType)
|
||||
{
|
||||
EntityType = entityType;
|
||||
|
||||
VirtualTableName = entityType.GetEntityTypeTableName();
|
||||
}
|
||||
|
||||
public IEntityType EntityType { get; }
|
||||
public string VirtualTableName { get; }
|
||||
}
|
||||
}
|
||||
// using Microsoft.EntityFrameworkCore.Metadata;
|
||||
// using ShardingCore.Core.EntityMetadatas;
|
||||
// using ShardingCore.Extensions.InternalExtensions;
|
||||
//
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Ver: 1.0
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
// namespace ShardingCore.Bootstrappers
|
||||
// {
|
||||
// /// <summary>
|
||||
// /// 分表、分库对象确定参数用来初始化<see cref="EntityMetadata"/>时所需的信息
|
||||
// /// </summary>
|
||||
// public class EntityMetadataEnsureParams
|
||||
// {
|
||||
// public EntityMetadataEnsureParams(IEntityType entityType)
|
||||
// {
|
||||
// EntityType = entityType;
|
||||
//
|
||||
// VirtualTableName = entityType.GetEntityTypeTableName();
|
||||
// }
|
||||
//
|
||||
// public IEntityType EntityType { get; }
|
||||
// public string VirtualTableName { get; }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -5,9 +5,12 @@ using System.Linq.Expressions;
|
|||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.EntityShardingMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
|
@ -38,32 +41,37 @@ namespace ShardingCore.Bootstrappers
|
|||
public class EntityMetadataInitializer<TShardingDbContext,TEntity>: IEntityMetadataInitializer where TShardingDbContext:DbContext,IShardingDbContext where TEntity:class
|
||||
{
|
||||
private static readonly ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> _logger=InternalLoggerFactory.CreateLogger<EntityMetadataInitializer<TShardingDbContext,TEntity>>();
|
||||
private const string QueryFilter = "QueryFilter";
|
||||
private readonly IEntityType _entityType;
|
||||
private readonly string _virtualTableName;
|
||||
private readonly Expression<Func<TEntity,bool>> _queryFilterExpression;
|
||||
// private const string QueryFilter = "QueryFilter";
|
||||
// private readonly IEntityType _entityType;
|
||||
// private readonly string _virtualTableName;
|
||||
// private readonly Expression<Func<TEntity,bool>> _queryFilterExpression;
|
||||
private readonly Type _shardingEntityType;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _shardingEntityConfigOptions;
|
||||
private readonly IVirtualDataSourceManager<TShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _virtualDataSourceRouteManager;
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IJobManager _jobManager;
|
||||
|
||||
public EntityMetadataInitializer(EntityMetadataEnsureParams entityMetadataEnsureParams,
|
||||
public EntityMetadataInitializer(
|
||||
IShardingEntityConfigOptions<TShardingDbContext> shardingEntityConfigOptions,
|
||||
IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager,
|
||||
IVirtualDataSourceRouteManager<TShardingDbContext> virtualDataSourceRouteManager,
|
||||
IVirtualTableManager<TShardingDbContext> virtualTableManager,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
|
||||
IJobManager jobManager
|
||||
)
|
||||
{
|
||||
_entityType = entityMetadataEnsureParams.EntityType;
|
||||
_virtualTableName = entityMetadataEnsureParams.VirtualTableName;
|
||||
_queryFilterExpression = entityMetadataEnsureParams.EntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as Expression<Func<TEntity, bool>>;
|
||||
_shardingEntityType = typeof(TEntity);
|
||||
// _entityType = entityMetadataEnsureParams.EntityType;
|
||||
// _virtualTableName = entityMetadataEnsureParams.VirtualTableName;
|
||||
// _queryFilterExpression = entityMetadataEnsureParams.EntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as Expression<Func<TEntity, bool>>;
|
||||
_shardingEntityConfigOptions = shardingEntityConfigOptions;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_jobManager = jobManager;
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
|
@ -74,17 +82,16 @@ namespace ShardingCore.Bootstrappers
|
|||
/// <exception cref="ShardingCoreInvalidOperationException"></exception>
|
||||
public void Initialize()
|
||||
{
|
||||
var shardingEntityType = _entityType.ClrType;
|
||||
var entityMetadata = new EntityMetadata(shardingEntityType, _virtualTableName,typeof(TShardingDbContext),_entityType.FindPrimaryKey()?.Properties?.Select(o=>o.PropertyInfo)?.ToList()??new List<PropertyInfo>(),_queryFilterExpression);
|
||||
var entityMetadata = new EntityMetadata(_shardingEntityType, typeof(TShardingDbContext));
|
||||
if (!_entityMetadataManager.AddEntityMetadata(entityMetadata))
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add entity metadata {shardingEntityType.FullName}");
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add entity metadata {_shardingEntityType.FullName}");
|
||||
//设置标签
|
||||
if (_shardingEntityConfigOptions.TryGetVirtualDataSourceRoute<TEntity>(out var virtualDataSourceRouteType))
|
||||
{
|
||||
var creatEntityMetadataDataSourceBuilder = EntityMetadataDataSourceBuilder<TEntity>.CreateEntityMetadataDataSourceBuilder(entityMetadata);
|
||||
//配置属性分库信息
|
||||
EntityMetadataHelper.Configure(creatEntityMetadataDataSourceBuilder);
|
||||
var dataSourceRoute = CreateVirtualDataSourceRoute(virtualDataSourceRouteType, entityMetadata);
|
||||
var dataSourceRoute = CreateVirtualDataSourceRoute(virtualDataSourceRouteType);
|
||||
if (dataSourceRoute is IEntityMetadataAutoBindInitializer entityMetadataAutoBindInitializer)
|
||||
{
|
||||
entityMetadataAutoBindInitializer.Initialize(entityMetadata);
|
||||
|
@ -107,7 +114,7 @@ namespace ShardingCore.Bootstrappers
|
|||
//配置属性分表信息
|
||||
EntityMetadataHelper.Configure(entityMetadataTableBuilder);
|
||||
|
||||
var virtualTableRoute = CreateVirtualTableRoute(virtualTableRouteType, entityMetadata);
|
||||
var virtualTableRoute = CreateVirtualTableRoute(virtualTableRouteType);
|
||||
if (virtualTableRoute is IEntityMetadataAutoBindInitializer entityMetadataAutoBindInitializer)
|
||||
{
|
||||
entityMetadataAutoBindInitializer.Initialize(entityMetadata);
|
||||
|
@ -119,60 +126,44 @@ namespace ShardingCore.Bootstrappers
|
|||
}
|
||||
//创建虚拟表
|
||||
var virtualTable = CreateVirtualTable(virtualTableRoute,entityMetadata);
|
||||
InitVirtualTable(virtualTable);
|
||||
_virtualTableManager.AddVirtualTable(virtualTable);
|
||||
//检测校验分表分库对象元数据
|
||||
entityMetadata.CheckShardingTableMetadata();
|
||||
//添加任务
|
||||
if (virtualTableRoute is IJob routeJob && routeJob.AutoCreateTableByTime())
|
||||
{
|
||||
var jobManager = ShardingContainer.GetService<IJobManager>();
|
||||
var jobEntry = JobEntryFactory.Create(routeJob);
|
||||
jobManager.AddJob(jobEntry);
|
||||
_jobManager.AddJob(jobEntry);
|
||||
}
|
||||
}
|
||||
entityMetadata.CheckGenericMetadata();
|
||||
}
|
||||
|
||||
private IVirtualDataSourceRoute<TEntity> CreateVirtualDataSourceRoute(Type virtualRouteType,EntityMetadata entityMetadata)
|
||||
private IVirtualDataSourceRoute<TEntity> CreateVirtualDataSourceRoute(Type virtualRouteType)
|
||||
{
|
||||
var constructors
|
||||
= virtualRouteType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
if (constructors.Length != 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"virtual route :[{virtualRouteType}] found more declared constructor ");
|
||||
}
|
||||
|
||||
var @params = constructors[0].GetParameters().Select(x => ShardingContainer.GetService(x.ParameterType))
|
||||
.ToArray();
|
||||
object o = Activator.CreateInstance(virtualRouteType, @params);
|
||||
return (IVirtualDataSourceRoute<TEntity>)o;
|
||||
var instance = ShardingRuntimeContext.GetInstance().CreateInstance(virtualRouteType);
|
||||
return (IVirtualDataSourceRoute<TEntity>)instance;
|
||||
}
|
||||
|
||||
|
||||
private IVirtualTableRoute<TEntity> CreateVirtualTableRoute(Type virtualRouteType, EntityMetadata entityMetadata)
|
||||
private IVirtualTableRoute<TEntity> CreateVirtualTableRoute(Type virtualRouteType)
|
||||
{
|
||||
var constructors
|
||||
= virtualRouteType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
|
||||
if (constructors.Length !=1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"virtual route :[{virtualRouteType}] found more declared constructor ");
|
||||
}
|
||||
var @params = constructors[0].GetParameters().Select(x => ShardingContainer.GetService(x.ParameterType))
|
||||
.ToArray();
|
||||
object o = Activator.CreateInstance(virtualRouteType, @params);
|
||||
return (IVirtualTableRoute<TEntity>)o;
|
||||
var instance = ShardingRuntimeContext.GetInstance().CreateInstance(virtualRouteType);
|
||||
return (IVirtualTableRoute<TEntity>)instance;
|
||||
}
|
||||
|
||||
private IVirtualTable<TEntity> CreateVirtualTable(IVirtualTableRoute<TEntity> virtualTableRoute,EntityMetadata entityMetadata)
|
||||
{
|
||||
return new DefaultVirtualTable<TEntity>(virtualTableRoute, entityMetadata);
|
||||
}
|
||||
private void InitVirtualTable(IVirtualTable virtualTable)
|
||||
{
|
||||
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
|
||||
{
|
||||
var defaultPhysicTable = new DefaultPhysicTable(virtualTable, tail);
|
||||
virtualTable.AddPhysicTable(defaultPhysicTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,15 +20,17 @@ namespace ShardingCore.Bootstrappers
|
|||
public class ShardingBootstrapper : IShardingBootstrapper
|
||||
{
|
||||
private readonly ILogger<ShardingBootstrapper> _logger;
|
||||
private readonly IServiceProvider _internalServiceProvider;
|
||||
private readonly IEnumerable<IDbContextTypeCollector> _dbContextTypeCollectors;
|
||||
private readonly IJobManager _jobManager;
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
|
||||
public ShardingBootstrapper(IServiceProvider serviceProvider,IEnumerable<IDbContextTypeCollector> dbContextTypeCollectors)
|
||||
public ShardingBootstrapper(IServiceProvider internalServiceProvider,IEnumerable<IDbContextTypeCollector> dbContextTypeCollectors,IJobManager jobManager)
|
||||
{
|
||||
ShardingContainer.SetServices(serviceProvider);
|
||||
InternalLoggerFactory.DefaultFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||
_logger = InternalLoggerFactory.DefaultFactory .CreateLogger<ShardingBootstrapper>();
|
||||
_internalServiceProvider = internalServiceProvider;
|
||||
_dbContextTypeCollectors = dbContextTypeCollectors;
|
||||
_jobManager = jobManager;
|
||||
}
|
||||
/// <summary>
|
||||
/// 启动
|
||||
|
@ -40,18 +42,17 @@ namespace ShardingCore.Bootstrappers
|
|||
_logger.LogDebug("sharding core starting......");
|
||||
foreach (var dbContextTypeCollector in _dbContextTypeCollectors)
|
||||
{
|
||||
var instance = (IShardingDbContextBootstrapper)ShardingContainer.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(dbContextTypeCollector.ShardingDbContextType));
|
||||
var instance = (IShardingDbContextBootstrapper)ActivatorUtilities.CreateInstance(_internalServiceProvider,typeof(ShardingDbContextBootstrapper<>).GetGenericType0(dbContextTypeCollector.ShardingDbContextType));
|
||||
_logger.LogDebug($"{dbContextTypeCollector.ShardingDbContextType} start init......");
|
||||
instance.Init();
|
||||
instance.Initialize();
|
||||
_logger.LogDebug($"{dbContextTypeCollector.ShardingDbContextType} complete init");
|
||||
}
|
||||
|
||||
var jobManager = ShardingContainer.GetService<IJobManager>();
|
||||
if (jobManager != null && jobManager.HasAnyJob())
|
||||
if (_jobManager != null && _jobManager.HasAnyJob())
|
||||
{
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
await ShardingContainer.GetService<JobRunnerService>().StartAsync();
|
||||
await _internalServiceProvider.GetRequiredService<JobRunnerService>().StartAsync();
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.TrackerManagers;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
@ -29,108 +33,107 @@ namespace ShardingCore.Bootstrappers
|
|||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
void Init();
|
||||
void Initialize();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分片具体DbContext初始化器
|
||||
/// </summary>
|
||||
public class ShardingDbContextBootstrapper<TShardingDbContext> : IShardingDbContextBootstrapper where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ShardingDbContextBootstrapper<TShardingDbContext> : IShardingDbContextBootstrapper
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IServiceProvider _internalServiceProvider;
|
||||
private readonly IVirtualDataSourceManager<TShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _entityConfigOptions;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IParallelTableManager<TShardingDbContext> _parallelTableManager;
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
|
||||
private readonly IDataSourceInitializer<TShardingDbContext> _dataSourceInitializer;
|
||||
private readonly ITrackerManager<TShardingDbContext> _trackerManager;
|
||||
|
||||
// private readonly ITrackerManager<TShardingDbContext> _trackerManager;
|
||||
private readonly Type _shardingDbContextType;
|
||||
|
||||
public ShardingDbContextBootstrapper(
|
||||
IServiceProvider internalServiceProvider,
|
||||
IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager,
|
||||
IShardingEntityConfigOptions<TShardingDbContext> entityConfigOptions,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
|
||||
IParallelTableManager<TShardingDbContext> parallelTableManager,
|
||||
IDataSourceInitializer<TShardingDbContext> dataSourceInitializer,
|
||||
ITrackerManager<TShardingDbContext> trackerManager)
|
||||
IVirtualTableManager<TShardingDbContext> virtualTableManager,
|
||||
IDataSourceInitializer<TShardingDbContext> dataSourceInitializer
|
||||
// ITrackerManager<TShardingDbContext> trackerManager
|
||||
)
|
||||
{
|
||||
_shardingDbContextType = typeof(TShardingDbContext);
|
||||
_internalServiceProvider = internalServiceProvider;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_entityConfigOptions = entityConfigOptions;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_parallelTableManager = parallelTableManager;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_dataSourceInitializer = dataSourceInitializer;
|
||||
_trackerManager = trackerManager;
|
||||
// _trackerManager = trackerManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public void Init()
|
||||
public void Initialize()
|
||||
{
|
||||
InitializeEntityMetadata();
|
||||
InitializeParallelTables();
|
||||
InitializeConfigure();
|
||||
// InitializeConfigure();
|
||||
}
|
||||
|
||||
private void InitializeEntityMetadata()
|
||||
{
|
||||
using (var serviceScope = ShardingContainer.ServiceProvider.CreateScope())
|
||||
var configId = _virtualDataSourceManager.GetAllVirtualDataSources().First().ConfigId;
|
||||
using (_virtualDataSourceManager.CreateScope(configId))
|
||||
{
|
||||
var configId = _virtualDataSourceManager.GetAllVirtualDataSources().First().ConfigId;
|
||||
using (_virtualDataSourceManager.CreateScope(configId))
|
||||
var shardingEntities = _entityConfigOptions.GetShardingTableRouteTypes()
|
||||
.Concat(_entityConfigOptions.GetShardingDataSourceRouteTypes()).ToHashSet();
|
||||
foreach (var entityType in shardingEntities)
|
||||
{
|
||||
//var dataSourceName = _virtualDataSource.DefaultDataSourceName;
|
||||
var entityMetadataInitializerType =
|
||||
typeof(EntityMetadataInitializer<,>).GetGenericType1(_shardingDbContextType, entityType);
|
||||
|
||||
using var context =
|
||||
(DbContext)serviceScope.ServiceProvider.GetService(_shardingDbContextType);
|
||||
foreach (var entity in context.Model.GetEntityTypes())
|
||||
{
|
||||
var entityType = entity.ClrType;
|
||||
|
||||
_trackerManager.AddDbContextModel(entityType,entity.FindPrimaryKey()!=null);
|
||||
//entity.GetAnnotation("")
|
||||
if (_entityConfigOptions.HasVirtualDataSourceRoute(entityType) ||
|
||||
_entityConfigOptions.HasVirtualTableRoute(entityType))
|
||||
{
|
||||
var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(_shardingDbContextType, entityType);
|
||||
|
||||
var entityMetadataInitializer = (IEntityMetadataInitializer)ShardingContainer.CreateInstanceWithInputParams(entityMetadataInitializerType, new EntityMetadataEnsureParams(entity));
|
||||
entityMetadataInitializer.Initialize();
|
||||
}
|
||||
}
|
||||
var entityMetadataInitializer =
|
||||
(IEntityMetadataInitializer)ActivatorUtilities.CreateInstance(_internalServiceProvider,entityMetadataInitializerType);
|
||||
entityMetadataInitializer.Initialize();
|
||||
|
||||
}
|
||||
//if (_shardingConfigOption.EnsureCreatedWithOutShardingTable)
|
||||
// EnsureCreated(context, dataSourceName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void InitializeParallelTables()
|
||||
{
|
||||
foreach (var parallelTableGroupNode in _entityConfigOptions.GetParallelTableGroupNodes())
|
||||
{
|
||||
var parallelTableComparerType = parallelTableGroupNode.GetEntities().FirstOrDefault(o => !_entityMetadataManager.IsShardingTable(o.Type));
|
||||
var parallelTableComparerType = parallelTableGroupNode.GetEntities()
|
||||
.FirstOrDefault(o => !_entityMetadataManager.IsShardingTable(o.Type));
|
||||
if (parallelTableComparerType != null)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{parallelTableComparerType.Type.Name} must is sharding table type");
|
||||
}
|
||||
|
||||
_parallelTableManager.AddParallelTable(parallelTableGroupNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeConfigure()
|
||||
{
|
||||
var allVirtualDataSources = _virtualDataSourceManager.GetAllVirtualDataSources();
|
||||
foreach (var virtualDataSource in allVirtualDataSources)
|
||||
{
|
||||
var dataSources = virtualDataSource.GetDataSources();
|
||||
foreach (var dataSourceKv in dataSources)
|
||||
{
|
||||
var dataSourceName = dataSourceKv.Key;
|
||||
var connectionString = dataSourceKv.Value;
|
||||
_dataSourceInitializer.InitConfigure(virtualDataSource,dataSourceName, connectionString, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// private void InitializeConfigure()
|
||||
// {
|
||||
// var allVirtualDataSources = _virtualDataSourceManager.GetAllVirtualDataSources();
|
||||
// foreach (var virtualDataSource in allVirtualDataSources)
|
||||
// {
|
||||
// var dataSources = virtualDataSource.GetDataSources();
|
||||
// foreach (var dataSourceKv in dataSources)
|
||||
// {
|
||||
// var dataSourceName = dataSourceKv.Key;
|
||||
// _dataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.EntityMetadatas
|
||||
|
@ -72,5 +74,10 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
{
|
||||
return _caches.ContainsKey(entityType);
|
||||
}
|
||||
|
||||
public List<Type> GetAllShardingEntities()
|
||||
{
|
||||
return _caches.Keys.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,14 +13,10 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// </summary>
|
||||
public class EntityMetadata
|
||||
{
|
||||
public EntityMetadata(Type entityType, string virtualTableName,Type shardingDbContextType, IReadOnlyList<PropertyInfo> primaryKeyProperties,LambdaExpression queryFilterExpression)
|
||||
public EntityMetadata(Type entityType, Type shardingDbContextType)
|
||||
{
|
||||
EntityType = entityType;
|
||||
VirtualTableName = virtualTableName;
|
||||
ShardingDbContextType = shardingDbContextType;
|
||||
PrimaryKeyProperties = primaryKeyProperties;
|
||||
QueryFilterExpression = queryFilterExpression;
|
||||
IsSingleKey= PrimaryKeyProperties.Count == 1;
|
||||
ShardingDataSourceProperties = new Dictionary<string, PropertyInfo>();
|
||||
ShardingTableProperties = new Dictionary<string, PropertyInfo>();
|
||||
}
|
||||
|
@ -28,27 +24,10 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// 分表类型 sharding entity type
|
||||
/// </summary>
|
||||
public Type EntityType { get; }
|
||||
/// <summary>
|
||||
/// 分表的原表名 original table name in db exclude tail
|
||||
/// </summary>
|
||||
public string VirtualTableName { get; }
|
||||
|
||||
|
||||
public Type ShardingDbContextType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public IReadOnlyList<PropertyInfo> PrimaryKeyProperties { get; }
|
||||
/**
|
||||
* efcore query filter
|
||||
*/
|
||||
public LambdaExpression QueryFilterExpression { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否单主键
|
||||
/// </summary>
|
||||
public bool IsSingleKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否多数据源
|
||||
/// </summary>
|
||||
|
@ -179,7 +158,7 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// </summary>
|
||||
public void CheckGenericMetadata()
|
||||
{
|
||||
if (null == EntityType || null == PrimaryKeyProperties || null == VirtualTableName ||
|
||||
if (null == EntityType ||
|
||||
(!IsMultiTableMapping && !IsMultiDataSourceMapping))
|
||||
{
|
||||
throw new ShardingCoreException($"not found entity:{EntityType} configure");
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
|
@ -41,5 +42,7 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
bool IsSharding(Type entityType);
|
||||
|
||||
List<Type> GetAllShardingEntities();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
namespace ShardingCore.Core
|
||||
{
|
||||
|
||||
public interface IShardingRuntimeModel
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
public interface IShardingRuntimeModelCacheFactory
|
||||
{
|
||||
object GetCacheKey<TDbContext>();
|
||||
object GetCacheKey(Type DbContext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace ShardingCore.Core
|
||||
{
|
||||
|
||||
public interface IShardingRuntimeModelOptions
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -23,28 +23,29 @@ namespace ShardingCore.Core.PhysicTables
|
|||
public DefaultPhysicTable(IVirtualTable virtualTable, string tail)
|
||||
{
|
||||
VirtualTable = virtualTable;
|
||||
OriginalName = virtualTable.GetVirtualTableName();
|
||||
// OriginalName = virtualTable.GetVirtualTableName();
|
||||
Tail = tail;
|
||||
EntityMetadata = VirtualTable.EntityMetadata;
|
||||
EntityType = EntityMetadata.EntityType;
|
||||
TableSeparator = EntityMetadata.TableSeparator;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 元数据对象
|
||||
/// </summary>
|
||||
public EntityMetadata EntityMetadata { get; }
|
||||
/// <summary>
|
||||
/// 全表名称
|
||||
/// </summary>
|
||||
public string FullName => $"{OriginalName}{TableSeparator}{Tail}";
|
||||
/// <summary>
|
||||
/// 原始表名
|
||||
/// </summary>
|
||||
public string OriginalName { get; }
|
||||
// /// <summary>
|
||||
// /// 全表名称
|
||||
// /// </summary>
|
||||
// public string FullName => $"{OriginalName}{TableSeparator}{Tail}";
|
||||
// /// <summary>
|
||||
// /// 原始表名
|
||||
// /// </summary>
|
||||
// public string OriginalName { get; }
|
||||
/// <summary>
|
||||
/// 分表的表名和后置的连接器默认为下划线"_" 可以为空
|
||||
/// </summary>
|
||||
public string TableSeparator => EntityMetadata.TableSeparator;
|
||||
public string TableSeparator { get; }
|
||||
/// <summary>
|
||||
/// 分表后缀
|
||||
/// </summary>
|
||||
|
@ -59,7 +60,7 @@ namespace ShardingCore.Core.PhysicTables
|
|||
public IVirtualTable VirtualTable { get; }
|
||||
protected bool Equals(DefaultPhysicTable other)
|
||||
{
|
||||
return OriginalName == other.OriginalName && Tail == other.Tail && Equals(EntityType, other.EntityType);
|
||||
return Tail == other.Tail && EntityType == other.EntityType;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -74,7 +75,7 @@ namespace ShardingCore.Core.PhysicTables
|
|||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(OriginalName, Tail, VirtualTable);
|
||||
return HashCode.Combine(TableSeparator, Tail, VirtualTable);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -84,7 +85,7 @@ namespace ShardingCore.Core.PhysicTables
|
|||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (OriginalName != null ? OriginalName.GetHashCode() : 0);
|
||||
var hashCode = (TableSeparator != null ? TableSeparator.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Tail != null ? Tail.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (VirtualTable != null ? VirtualTable.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
|
|
|
@ -19,14 +19,14 @@ namespace ShardingCore.Core.PhysicTables
|
|||
/// 对象信息
|
||||
/// </summary>
|
||||
EntityMetadata EntityMetadata { get; }
|
||||
/// <summary>
|
||||
/// 表全称
|
||||
/// </summary>
|
||||
string FullName { get; }
|
||||
/// <summary>
|
||||
/// 原表名称
|
||||
/// </summary>
|
||||
string OriginalName { get; }
|
||||
// /// <summary>
|
||||
// /// 表全称
|
||||
// /// </summary>
|
||||
// string FullName { get; }
|
||||
// /// <summary>
|
||||
// /// 原表名称
|
||||
// /// </summary>
|
||||
// string OriginalName { get; }
|
||||
/// <summary>
|
||||
/// 尾巴前缀 tail prefix
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,180 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Bootstrappers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Logger;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
||||
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
public sealed class ShardingRuntimeContext
|
||||
{
|
||||
private bool isInited = false;
|
||||
private object INIT_LOCK = new object();
|
||||
private IServiceCollection _serviceMap = new ServiceCollection();
|
||||
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IServiceProvider _applicationServiceProvider;
|
||||
|
||||
|
||||
private ShardingRuntimeContext()
|
||||
{
|
||||
}
|
||||
|
||||
private static readonly ShardingRuntimeContext _instance = new ShardingRuntimeContext();
|
||||
public static ShardingRuntimeContext GetInstance() => _instance;
|
||||
|
||||
|
||||
public void AddServiceConfig(Action<IServiceCollection> configure)
|
||||
{
|
||||
CheckIfBuild();
|
||||
configure(_serviceMap);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
// var shardingRuntimeModelCacheFactory = _serviceProvider.GetRequiredService<IShardingRuntimeModelCacheFactory>();
|
||||
// var cacheKey = shardingRuntimeModelCacheFactory.GetCacheKey(dbContext.GetType());
|
||||
// var memoryCache = _serviceProvider.GetRequiredService<IMemoryCache>();
|
||||
// if (!memoryCache.TryGetValue(cacheKey, out IShardingRuntimeModel model))
|
||||
// {
|
||||
//
|
||||
// // Make sure OnModelCreating really only gets called once, since it may not be thread safe.
|
||||
// var acquire = Monitor.TryEnter(INIT_LOCK, TimeSpan.FromSeconds(waitSeconds));
|
||||
// if (!acquire)
|
||||
// {
|
||||
// throw new ShardingCoreInvalidOperationException("cache model timeout");
|
||||
// }
|
||||
// try
|
||||
// {
|
||||
// if (!cache.TryGetValue(cacheKey, out model))
|
||||
// {
|
||||
// model = CreateModel(
|
||||
// context, modelCreationDependencies.ConventionSetBuilder, modelCreationDependencies.ModelDependencies);
|
||||
//
|
||||
// model = modelCreationDependencies.ModelRuntimeInitializer.Initialize(
|
||||
// model, designTime, modelCreationDependencies.ValidationLogger);
|
||||
//
|
||||
// model = cache.Set(cacheKey, model, new MemoryCacheEntryOptions { Size = size, Priority = priority });
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// Monitor.Exit(_syncObject);
|
||||
// }
|
||||
// }
|
||||
if (isInited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (INIT_LOCK)
|
||||
{
|
||||
|
||||
if (isInited)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
_serviceProvider = _serviceMap.BuildServiceProvider();
|
||||
_serviceProvider.GetRequiredService<IShardingBootstrapper>().Start();
|
||||
isInited = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void UseLogfactory(ILoggerFactory loggerFactory)
|
||||
{
|
||||
InternalLoggerFactory.DefaultFactory = loggerFactory;
|
||||
}
|
||||
|
||||
public void WithApplicationServiceProvider(IServiceProvider applicationServiceProvider)
|
||||
{
|
||||
_applicationServiceProvider = applicationServiceProvider;
|
||||
}
|
||||
|
||||
private void CheckIfBuild()
|
||||
{
|
||||
if (isInited)
|
||||
throw new InvalidOperationException("sharding runtime already build");
|
||||
}
|
||||
private void CheckIfNotBuild()
|
||||
{
|
||||
if (isInited)
|
||||
throw new InvalidOperationException("sharding runtime not init");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取的
|
||||
/// </summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public object CreateInstance(Type serviceType)
|
||||
{
|
||||
var constructors
|
||||
= serviceType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
|
||||
if (constructors.Length != 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"type :[{serviceType}] found more than one declared constructor ");
|
||||
}
|
||||
var @params = constructors[0].GetParameters().Select(x => GetRequiredService(x.ParameterType))
|
||||
.ToArray();
|
||||
return Activator.CreateInstance(serviceType, @params);
|
||||
}
|
||||
|
||||
public object GetService(Type serviceType)
|
||||
{
|
||||
CheckIfNotBuild();
|
||||
return _serviceProvider.GetService(serviceType);
|
||||
}
|
||||
|
||||
public TService GetService<TService>()
|
||||
{
|
||||
CheckIfNotBuild();
|
||||
return _serviceProvider.GetService<TService>();
|
||||
}
|
||||
private object GetRequiredService(Type serviceType)
|
||||
{
|
||||
var service = _serviceProvider?.GetService(serviceType);
|
||||
if (service == null)
|
||||
{
|
||||
service= _applicationServiceProvider?.GetService(serviceType);
|
||||
}
|
||||
|
||||
if (service == null)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException($"cant unable resolve service:[{serviceType}]");
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
public IShardingRouteManager GetShardingRouteManager()
|
||||
{
|
||||
return GetService<IShardingRouteManager>();
|
||||
}
|
||||
|
||||
public IShardingEntityConfigOptions<TShardingDbContext> GetRequiredShardingEntityConfigOption<TShardingDbContext>()
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return (IShardingEntityConfigOptions<TShardingDbContext>)GetRequiredShardingEntityConfigOption(typeof(TShardingDbContext));
|
||||
}
|
||||
public IShardingEntityConfigOptions GetRequiredShardingEntityConfigOption(Type shardingDbContextType)
|
||||
{
|
||||
return (IShardingEntityConfigOptions)GetService(typeof(IShardingEntityConfigOptions<>).GetGenericType0(shardingDbContextType));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// namespace ShardingCore.Core
|
||||
// {
|
||||
//
|
||||
// public class ShardingRuntimeOptions
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// }
|
|
@ -107,10 +107,10 @@ namespace ShardingCore.Core.VirtualTables
|
|||
return _physicTables.TryAdd(physicTable, null);
|
||||
}
|
||||
|
||||
public string GetVirtualTableName()
|
||||
{
|
||||
return EntityMetadata.VirtualTableName;
|
||||
}
|
||||
// public string GetVirtualTableName()
|
||||
// {
|
||||
// return EntityMetadata.VirtualTableName;
|
||||
// }
|
||||
|
||||
IVirtualTableRoute IVirtualTable.GetVirtualRoute()
|
||||
{
|
||||
|
|
|
@ -59,11 +59,11 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <param name="physicTable"></param>
|
||||
/// <returns>添加成功</returns>
|
||||
bool AddPhysicTable(IPhysicTable physicTable);
|
||||
/// <summary>
|
||||
/// 获取原始表名 get original table name
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetVirtualTableName();
|
||||
// /// <summary>
|
||||
// /// 获取原始表名 get original table name
|
||||
// /// </summary>
|
||||
// /// <returns></returns>
|
||||
// string GetVirtualTableName();
|
||||
/// <summary>
|
||||
/// 获取当前虚拟表的路由 get this virtual table route
|
||||
/// </summary>
|
||||
|
|
|
@ -35,20 +35,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualTables
|
|||
/// <returns></returns>
|
||||
IVirtualTable TryGetVirtualTable(Type shardingEntityType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by actual table name
|
||||
/// </summary>
|
||||
/// <param name="virtualTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(string virtualTableName);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取虚拟表没有返回null
|
||||
/// </summary>
|
||||
/// <param name="virtualTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable TryGetVirtualTable(string virtualTableName);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的虚拟表 get all virtual table
|
||||
/// </summary>
|
||||
|
|
|
@ -29,7 +29,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualTables
|
|||
/// {entityType,virtualTableType}
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<Type, IVirtualTable> _shardingVirtualTables = new ConcurrentDictionary<Type, IVirtualTable>();
|
||||
private readonly ConcurrentDictionary<string, IVirtualTable> _shardingVirtualTaleVirtualTables = new ConcurrentDictionary<string, IVirtualTable>();
|
||||
public VirtualTableManager(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
|
@ -38,7 +37,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualTables
|
|||
public bool AddVirtualTable(IVirtualTable virtualTable)
|
||||
{
|
||||
var result = _shardingVirtualTables.TryAdd(virtualTable.EntityMetadata.EntityType, virtualTable);
|
||||
_shardingVirtualTaleVirtualTables.TryAdd(virtualTable.GetVirtualTableName(), virtualTable);
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -63,21 +61,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualTables
|
|||
return null;
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable(string virtualTableName)
|
||||
{
|
||||
if (!_shardingVirtualTaleVirtualTables.TryGetValue(virtualTableName, out var virtualTable))
|
||||
throw new ShardingCoreException($"virtual table not found virtual table name: {virtualTableName}");
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTable(string virtualTableName)
|
||||
{
|
||||
if (!_shardingVirtualTaleVirtualTables.TryGetValue(virtualTableName, out var virtualTable))
|
||||
return null;
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public ISet<IVirtualTable> GetAllVirtualTables()
|
||||
{
|
||||
return _shardingVirtualTables.Select(o => o.Value).ToHashSet();
|
||||
|
|
|
@ -25,8 +25,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
public abstract class AbstractShardingFilterVirtualDataSourceRoute<TEntity, TKey> : AbstractVirtualDataSourceRoute<TEntity, TKey> where TEntity : class
|
||||
{
|
||||
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>ShardingRuntimeContext.GetInstance().GetShardingRouteManager().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
|
|
|
@ -48,8 +48,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
//}
|
||||
|
||||
|
||||
EntityConfigOptions =
|
||||
ShardingContainer.GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
EntityConfigOptions =ShardingRuntimeContext.GetInstance().GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
|
||||
}
|
||||
public virtual IPaginationConfiguration<TEntity> CreatePaginationConfiguration()
|
||||
|
|
|
@ -26,8 +26,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
/// <typeparam name="TKey"></typeparam>
|
||||
public abstract class AbstractShardingFilterVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class
|
||||
{
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>ShardingRuntimeContext.GetInstance().GetShardingRouteManager().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
|
|
|
@ -67,11 +67,11 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
|
||||
if (physicTables.IsEmpty())
|
||||
{
|
||||
throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", allPhysicTables.Select(o=>o.FullName))}]");
|
||||
throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", allPhysicTables.Select(o=>o.EntityType))}]");
|
||||
}
|
||||
|
||||
if (physicTables.Count > 1)
|
||||
throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
||||
throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.EntityType}]"))}");
|
||||
return physicTables[0];
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
throw new ShardingCoreInvalidOperationException("already init");
|
||||
EntityMetadata = entityMetadata;
|
||||
|
||||
EntityConfigOptions =
|
||||
ShardingContainer.GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
EntityConfigOptions =ShardingRuntimeContext.GetInstance().GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails
|
|||
_tableRouteResult = tableRouteResult;
|
||||
_modelCacheKey = RANDOM_MODEL_CACHE_KEY+Guid.NewGuid().ToString("n");
|
||||
_entityTypes = tableRouteResult.ReplaceTables.Select(o=>o.EntityType).ToHashSet();
|
||||
var entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(tableRouteResult.ShardingDbContextType));
|
||||
var entityMetadataManager = (IEntityMetadataManager)ShardingRuntimeContext.GetInstance().GetService(typeof(IEntityMetadataManager<>).GetGenericType0(tableRouteResult.ShardingDbContextType));
|
||||
_isShardingTableQuery = _entityTypes.Any(o => entityMetadataManager.IsShardingTable(o));
|
||||
}
|
||||
public string GetRouteTailIdentity()
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
|
@ -15,7 +16,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
public interface ITableRouteRuleEngineFactory
|
||||
{
|
||||
//TableRouteRuleContext CreateContext(IQueryable queryable);
|
||||
IEnumerable<TableRouteResult> Route(IQueryable queryable,Dictionary<Type,IQueryable> queryEntities);
|
||||
IEnumerable<TableRouteResult> Route(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,Dictionary<Type,IQueryable> queryEntities);
|
||||
//IEnumerable<TableRouteResult> Route(TableRouteRuleContext ruleContext);
|
||||
}
|
||||
public interface ITableRouteRuleEngineFactory<TShardingDbContext> : ITableRouteRuleEngineFactory
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
}
|
||||
public string GetPrintInfo()
|
||||
{
|
||||
return $"(has different tail:{HasDifferentTail},current table:[{string.Join(",", ReplaceTables.Select(o => o.FullName))}])";
|
||||
return $"(has different tail:{HasDifferentTail},current table:[{string.Join(",", ReplaceTables.Select(o => o.EntityType))}])";
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
|
@ -15,12 +16,14 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
public class TableRouteRuleContext
|
||||
{
|
||||
|
||||
public TableRouteRuleContext(IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
|
||||
public TableRouteRuleContext(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
|
||||
{
|
||||
DataSourceRouteResult = dataSourceRouteResult;
|
||||
Queryable = queryable;
|
||||
QueryEntities = queryEntities;
|
||||
}
|
||||
|
||||
public DataSourceRouteResult DataSourceRouteResult { get; }
|
||||
public IQueryable Queryable { get; }
|
||||
public Dictionary<Type, IQueryable> QueryEntities { get; }
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
|
@ -31,14 +32,13 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
private TableRouteRuleContext CreateContext(IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
|
||||
private TableRouteRuleContext CreateContext(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
|
||||
{
|
||||
return new TableRouteRuleContext(queryable,queryEntities);
|
||||
return new TableRouteRuleContext(dataSourceRouteResult,queryable,queryEntities);
|
||||
}
|
||||
|
||||
public IEnumerable<TableRouteResult> Route(IQueryable queryable,Dictionary<Type,IQueryable> queryEntities)
|
||||
public IEnumerable<TableRouteResult> Route(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
|
||||
{
|
||||
var ruleContext = CreateContext(queryable, queryEntities);
|
||||
var ruleContext = CreateContext(dataSourceRouteResult,queryable, queryEntities);
|
||||
return Route(ruleContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,42 +48,38 @@ namespace ShardingCore.DynamicDataSources
|
|||
_tableCreator = shardingTableCreator;
|
||||
}
|
||||
|
||||
public void InitConfigure(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName,
|
||||
string connectionString, bool isOnStart, bool? needCreateDatabase=null, bool? needCreateTable = null)
|
||||
public void InitConfigure(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName)
|
||||
{
|
||||
using (var serviceScope = ShardingContainer.ServiceProvider.CreateScope())
|
||||
{
|
||||
using (_virtualDataSourceManager.CreateScope(virtualDataSource.ConfigId))
|
||||
{
|
||||
using (var context = serviceScope.ServiceProvider.GetService<TShardingDbContext>())
|
||||
{
|
||||
var createDatabase = !needCreateDatabase.HasValue || needCreateDatabase.Value;
|
||||
// var createDatabase = !needCreateDatabase.HasValue || needCreateDatabase.Value;
|
||||
//
|
||||
// if ((_entityConfigOptions.EnsureCreatedWithOutShardingTable || !isOnStart)&&createDatabase)
|
||||
// EnsureCreated(virtualDataSource, context, dataSourceName);
|
||||
// else if (_entityConfigOptions.CreateDataBaseOnlyOnStart.GetValueOrDefault()&& createDatabase)
|
||||
// {
|
||||
// EnsureCreateDataBaseOnly(context, dataSourceName);
|
||||
// }
|
||||
|
||||
if ((_entityConfigOptions.EnsureCreatedWithOutShardingTable || !isOnStart)&&createDatabase)
|
||||
EnsureCreated(virtualDataSource, context, dataSourceName);
|
||||
else if (_entityConfigOptions.CreateDataBaseOnlyOnStart.GetValueOrDefault()&& createDatabase)
|
||||
// var tableEnsureManager = virtualDataSource.ConfigurationParams.TableEnsureManager;
|
||||
// ////获取数据库存在的所有的表
|
||||
// var existTables = tableEnsureManager?.GetExistTables(context, dataSourceName) ??
|
||||
// new HashSet<string>();
|
||||
var allShardingEntities = _entityMetadataManager.GetAllShardingEntities();
|
||||
foreach (var entityType in allShardingEntities)
|
||||
{
|
||||
EnsureCreateDataBaseOnly(context, dataSourceName);
|
||||
}
|
||||
|
||||
var tableEnsureManager = virtualDataSource.ConfigurationParams.TableEnsureManager;
|
||||
////获取数据库存在的所有的表
|
||||
var existTables = tableEnsureManager?.GetExistTables(context, dataSourceName) ??
|
||||
new HashSet<string>();
|
||||
foreach (var entity in context.Model.GetEntityTypes())
|
||||
{
|
||||
var entityType = entity.ClrType;
|
||||
//如果是默认数据源
|
||||
if (virtualDataSource.IsDefault(dataSourceName))
|
||||
{
|
||||
if (_entityMetadataManager.IsShardingTable(entityType))
|
||||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(entityType);
|
||||
//创建表
|
||||
CreateDataTable(dataSourceName, virtualTable, existTables, isOnStart, needCreateTable);
|
||||
InitVirtualTable(virtualTable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//非默认数据源
|
||||
if (_entityMetadataManager.IsShardingDataSource(entityType))
|
||||
{
|
||||
var virtualDataSourceRoute = virtualDataSource.GetRoute(entityType);
|
||||
|
@ -93,113 +89,87 @@ namespace ShardingCore.DynamicDataSources
|
|||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(entityType);
|
||||
//创建表
|
||||
CreateDataTable(dataSourceName, virtualTable, existTables, isOnStart,needCreateTable);
|
||||
InitVirtualTable(virtualTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDataTable(string dataSourceName, IVirtualTable virtualTable, ISet<string> existTables,
|
||||
bool isOnStart,bool? needCreateTable)
|
||||
private void InitVirtualTable(IVirtualTable virtualTable)
|
||||
{
|
||||
var entityMetadata = virtualTable.EntityMetadata;
|
||||
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
|
||||
{
|
||||
var defaultPhysicTable = new DefaultPhysicTable(virtualTable, tail);
|
||||
if ((NeedCreateTable(entityMetadata) || !isOnStart)&&(!needCreateTable.HasValue|| needCreateTable.Value))
|
||||
{
|
||||
try
|
||||
{
|
||||
//添加物理表
|
||||
virtualTable.AddPhysicTable(defaultPhysicTable);
|
||||
if (!existTables.Contains(defaultPhysicTable.FullName))
|
||||
_tableCreator.CreateTable(dataSourceName, entityMetadata.EntityType, tail);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!_entityConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||
{
|
||||
_logger.LogWarning(e,
|
||||
$"table :{virtualTable.GetVirtualTableName()}{entityMetadata.TableSeparator}{tail} will created.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//添加物理表
|
||||
virtualTable.AddPhysicTable(defaultPhysicTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool NeedCreateTable(EntityMetadata entityMetadata)
|
||||
{
|
||||
if (entityMetadata.AutoCreateTable.HasValue)
|
||||
{
|
||||
if (entityMetadata.AutoCreateTable.Value)
|
||||
return entityMetadata.AutoCreateTable.Value;
|
||||
else
|
||||
{
|
||||
if (entityMetadata.AutoCreateDataSourceTable.HasValue)
|
||||
return entityMetadata.AutoCreateDataSourceTable.Value;
|
||||
}
|
||||
}
|
||||
|
||||
if (entityMetadata.AutoCreateDataSourceTable.HasValue)
|
||||
{
|
||||
if (entityMetadata.AutoCreateDataSourceTable.Value)
|
||||
return entityMetadata.AutoCreateDataSourceTable.Value;
|
||||
else
|
||||
{
|
||||
if (entityMetadata.AutoCreateTable.HasValue)
|
||||
return entityMetadata.AutoCreateTable.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return _entityConfigOptions.CreateShardingTableOnStart.GetValueOrDefault();
|
||||
}
|
||||
|
||||
private void EnsureCreated(IVirtualDataSource<TShardingDbContext> virtualDataSource, DbContext context,
|
||||
string dataSourceName)
|
||||
{
|
||||
if (context is IShardingDbContext shardingDbContext)
|
||||
{
|
||||
using (var dbContext =
|
||||
shardingDbContext.GetDbContext(dataSourceName, false,
|
||||
_routeTailFactory.Create(string.Empty, false)))
|
||||
{
|
||||
var isDefault = virtualDataSource.IsDefault(dataSourceName);
|
||||
|
||||
if (isDefault)
|
||||
{
|
||||
dbContext.RemoveDbContextRelationModelThatIsShardingTable();
|
||||
}
|
||||
else
|
||||
{
|
||||
dbContext.RemoveDbContextAllRelationModelThatIsNoSharding();
|
||||
}
|
||||
|
||||
dbContext.Database.EnsureCreated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureCreateDataBaseOnly(DbContext context, string dataSourceName)
|
||||
{
|
||||
if (context is IShardingDbContext shardingDbContext)
|
||||
{
|
||||
using (var dbContext = shardingDbContext.GetDbContext(dataSourceName, false,
|
||||
_routeTailFactory.Create(string.Empty, false)))
|
||||
{
|
||||
dbContext.RemoveDbContextAllRelationModel();
|
||||
dbContext.Database.EnsureCreated();
|
||||
}
|
||||
virtualTable.AddPhysicTable(defaultPhysicTable);
|
||||
}
|
||||
}
|
||||
//
|
||||
// private bool NeedCreateTable(EntityMetadata entityMetadata)
|
||||
// {
|
||||
// if (entityMetadata.AutoCreateTable.HasValue)
|
||||
// {
|
||||
// if (entityMetadata.AutoCreateTable.Value)
|
||||
// return entityMetadata.AutoCreateTable.Value;
|
||||
// else
|
||||
// {
|
||||
// if (entityMetadata.AutoCreateDataSourceTable.HasValue)
|
||||
// return entityMetadata.AutoCreateDataSourceTable.Value;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (entityMetadata.AutoCreateDataSourceTable.HasValue)
|
||||
// {
|
||||
// if (entityMetadata.AutoCreateDataSourceTable.Value)
|
||||
// return entityMetadata.AutoCreateDataSourceTable.Value;
|
||||
// else
|
||||
// {
|
||||
// if (entityMetadata.AutoCreateTable.HasValue)
|
||||
// return entityMetadata.AutoCreateTable.Value;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return _entityConfigOptions.CreateShardingTableOnStart.GetValueOrDefault();
|
||||
// }
|
||||
//
|
||||
// private void EnsureCreated(IVirtualDataSource<TShardingDbContext> virtualDataSource, DbContext context,
|
||||
// string dataSourceName)
|
||||
// {
|
||||
// if (context is IShardingDbContext shardingDbContext)
|
||||
// {
|
||||
// using (var dbContext =
|
||||
// shardingDbContext.GetDbContext(dataSourceName, false,
|
||||
// _routeTailFactory.Create(string.Empty, false)))
|
||||
// {
|
||||
// var isDefault = virtualDataSource.IsDefault(dataSourceName);
|
||||
//
|
||||
// if (isDefault)
|
||||
// {
|
||||
// dbContext.RemoveDbContextRelationModelThatIsShardingTable();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dbContext.RemoveDbContextAllRelationModelThatIsNoSharding();
|
||||
// }
|
||||
//
|
||||
// dbContext.Database.EnsureCreated();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void EnsureCreateDataBaseOnly(DbContext context, string dataSourceName)
|
||||
// {
|
||||
// if (context is IShardingDbContext shardingDbContext)
|
||||
// {
|
||||
// using (var dbContext = shardingDbContext.GetDbContext(dataSourceName, false,
|
||||
// _routeTailFactory.Create(string.Empty, false)))
|
||||
// {
|
||||
// dbContext.RemoveDbContextAllRelationModel();
|
||||
// dbContext.Database.EnsureCreated();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -16,10 +16,6 @@ namespace ShardingCore.DynamicDataSources
|
|||
/// </summary>
|
||||
/// <param name="virtualDataSource"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <param name="isOnStart">当前是否是启动时被调用</param>
|
||||
/// <param name="needCreateDatabase">当前是否是启动时被调用</param>
|
||||
/// <param name="needCreateTable">当前是否是启动时被调用</param>
|
||||
void InitConfigure(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName, string connectionString, bool isOnStart, bool? needCreateDatabase = null, bool? needCreateTable = null);
|
||||
void InitConfigure(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,12 +17,18 @@ namespace ShardingCore.EFCores.OptionsExtensions
|
|||
#if EFCORE6
|
||||
public class ShardingWrapOptionsExtension : IDbContextOptionsExtension
|
||||
{
|
||||
public ShardingWrapOptionsExtension()
|
||||
{
|
||||
Console.WriteLine("ShardingWrapOptionsExtension ctor");
|
||||
}
|
||||
public void ApplyServices(IServiceCollection services)
|
||||
{
|
||||
Console.WriteLine("ShardingWrapOptionsExtension ApplyServices");
|
||||
}
|
||||
|
||||
public void Validate(IDbContextOptions options)
|
||||
{
|
||||
Console.WriteLine("ShardingWrapOptionsExtension Validate");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// using System;
|
||||
// using Microsoft.EntityFrameworkCore;
|
||||
// using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
// using Microsoft.EntityFrameworkCore.Internal;
|
||||
// using Microsoft.EntityFrameworkCore.Metadata;
|
||||
//
|
||||
// namespace ShardingCore.EFCores
|
||||
// {
|
||||
//
|
||||
//
|
||||
// public class ShardingDbContextServices:DbContextServices
|
||||
// {
|
||||
// public override IDbContextServices Initialize(IServiceProvider scopedProvider, DbContextOptions contextOptions, DbContext context)
|
||||
// {
|
||||
// base.Initialize(scopedProvider, contextOptions, context);
|
||||
// shardingrun
|
||||
// context
|
||||
// return this;
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -10,6 +10,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core;
|
||||
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
|
@ -26,7 +27,7 @@ namespace ShardingCore.EFCores
|
|||
{
|
||||
_shardingDbContext = currentContext.Context as IShardingDbContext ??
|
||||
throw new ShardingCoreException("db context operator is not IShardingDbContext");
|
||||
_shardingCompilerExecutor = ShardingContainer.GetService<IShardingCompilerExecutor>();
|
||||
_shardingCompilerExecutor = ShardingRuntimeContext.GetInstance().GetService<IShardingCompilerExecutor>();
|
||||
}
|
||||
|
||||
public TResult Execute<TResult>(Expression query)
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace ShardingCore.Jobs.Abstaractions
|
|||
* @Date: Wednesday, 06 January 2021 13:10:13
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
internal interface IJobManager
|
||||
public interface IJobManager
|
||||
{
|
||||
void AddJob(JobEntry jobEntry);
|
||||
bool HasAnyJob();
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ShardingCore.Jobs.Impls
|
|||
* @Date: Wednesday, 06 January 2021 13:13:23
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
internal class JobEntry
|
||||
public sealed class JobEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// 保证多线程只有一个清理操作
|
||||
|
|
|
@ -17,6 +17,8 @@ namespace ShardingCore.Sharding.MergeEngines.ParallelControl
|
|||
|
||||
public bool IsUnDo()
|
||||
{
|
||||
if (Status == Did)
|
||||
return false;
|
||||
return Interlocked.CompareExchange(ref Status, Did, UnDo) == UnDo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using ShardingCore.Sharding.ShardingExecutors.QueryableCombines;
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
using ShardingCore.Logger;
|
||||
using ShardingCore.Sharding.Parsers.Abstractions;
|
||||
|
@ -47,8 +48,8 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
|
||||
var queryableCombine = GetQueryableCombine(queryCompilerContext);
|
||||
_logger.LogDebug($"queryable combine:{queryableCombine.GetType()}");
|
||||
var dataSourceRouteRuleEngineFactory = (IDataSourceRouteRuleEngineFactory)ShardingContainer.GetService(typeof(IDataSourceRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
|
||||
var tableRouteRuleEngineFactory = (ITableRouteRuleEngineFactory)ShardingContainer.GetService(typeof(ITableRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
|
||||
var dataSourceRouteRuleEngineFactory = (IDataSourceRouteRuleEngineFactory)ShardingRuntimeContext.GetInstance().GetService(typeof(IDataSourceRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
|
||||
var tableRouteRuleEngineFactory = (ITableRouteRuleEngineFactory)ShardingRuntimeContext.GetInstance().GetService(typeof(ITableRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
|
||||
_logger.LogLazyDebug(() => $"queryable combine before:{queryCompilerContext.GetQueryExpression().ShardingPrint()}");
|
||||
var queryCombineResult = queryableCombine.Combine(queryCompilerContext);
|
||||
_logger.LogLazyDebug(() => $"queryable combine after:{queryCombineResult.GetCombineQueryable().ShardingPrint()}");
|
||||
|
|
|
@ -1,194 +1,194 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.TrackerManagers;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 02 January 2021 19:37:27
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 分片容器全局唯一提供静态依赖注入<code>IServiceProvider</code>
|
||||
/// </summary>
|
||||
public class ShardingContainer
|
||||
{
|
||||
private ShardingContainer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static IServiceProvider serviceProvider;
|
||||
|
||||
public static IServiceProvider ServiceProvider
|
||||
{
|
||||
get { return serviceProvider ?? throw new ShardingCoreInvalidOperationException("sharding core not start"); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 静态注入
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
public static void SetServices(IServiceProvider services)
|
||||
{
|
||||
if (serviceProvider == null)
|
||||
serviceProvider = services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取服务
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T GetService<T>()
|
||||
{
|
||||
return ServiceProvider.GetService<T>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取服务集合
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<T> GetServices<T>()
|
||||
{
|
||||
return ServiceProvider.GetServices<T>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 根据类型获取服务
|
||||
/// </summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <returns></returns>
|
||||
public static object GetService(Type serviceType)
|
||||
{
|
||||
return ServiceProvider.GetService(serviceType);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取的
|
||||
/// </summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public static object CreateInstance(Type serviceType)
|
||||
{
|
||||
var constructors
|
||||
= serviceType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
|
||||
if (constructors.Length != 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"type :[{serviceType}] found more than one declared constructor ");
|
||||
}
|
||||
var @params = constructors[0].GetParameters().Select(x => ServiceProvider.GetService(x.ParameterType))
|
||||
.ToArray();
|
||||
return Activator.CreateInstance(serviceType, @params);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取并且也存在自行传入的参数,优先判断自行传入的参数
|
||||
/// </summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public static object CreateInstanceWithInputParams(Type serviceType, params object[] args)
|
||||
{
|
||||
var constructors
|
||||
= serviceType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
|
||||
if (constructors.Length != 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"type :[{serviceType}] found more than one declared constructor ");
|
||||
}
|
||||
|
||||
var argIsNotEmpty = args.IsNotEmpty();
|
||||
var @params = constructors[0].GetParameters().Select(x =>
|
||||
{
|
||||
if (argIsNotEmpty)
|
||||
{
|
||||
var arg = args.FirstOrDefault(o => o.GetType() == x.ParameterType);
|
||||
if (arg != null)
|
||||
return arg;
|
||||
}
|
||||
return ServiceProvider.GetService(x.ParameterType);
|
||||
})
|
||||
.ToArray();
|
||||
return Activator.CreateInstance(serviceType, @params);
|
||||
}
|
||||
|
||||
//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 (IShardingEntityConfigOptions<TShardingDbContext>)GetRequiredShardingEntityConfigOption(typeof(TShardingDbContext));
|
||||
}
|
||||
public static IShardingEntityConfigOptions GetRequiredShardingEntityConfigOption(Type 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> GetRequiredCurrentVirtualDataSource<TShardingDbContext>()
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return GetRequiredVirtualDataSourceManager<TShardingDbContext>().GetCurrentVirtualDataSource() ?? throw new InvalidOperationException("cant resolve CurrentVirtualDataSource");
|
||||
}
|
||||
public static IVirtualDataSource GetRequiredCurrentVirtualDataSource(Type shardingDbContextType)
|
||||
{
|
||||
return GetRequiredVirtualDataSourceManager(shardingDbContextType).GetCurrentVirtualDataSource()??throw new InvalidOperationException("cant resolve CurrentVirtualDataSource");
|
||||
}
|
||||
|
||||
public static IEntityMetadataManager GetRequiredEntityMetadataManager(Type shardingDbContextType)
|
||||
{
|
||||
return (IEntityMetadataManager)ServiceProvider.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContextType));
|
||||
}
|
||||
|
||||
public static IEntityMetadataManager<TShardingDbContext> GetRequiredEntityMetadataManager<TShardingDbContext>()
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return (IEntityMetadataManager<TShardingDbContext>)GetRequiredEntityMetadataManager(typeof(TShardingDbContext));
|
||||
}
|
||||
|
||||
public static ITrackerManager GetTrackerManager(Type shardingDbContextType)
|
||||
{
|
||||
return (ITrackerManager)ServiceProvider.GetService(typeof(ITrackerManager<>).GetGenericType0(shardingDbContextType));
|
||||
}
|
||||
|
||||
public static IVirtualTableManager GetVirtualTableManager(Type shardingDbContextType)
|
||||
{
|
||||
return (IVirtualTableManager)ServiceProvider.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContextType));
|
||||
}
|
||||
}
|
||||
}
|
||||
// using Microsoft.EntityFrameworkCore;
|
||||
// using Microsoft.Extensions.DependencyInjection;
|
||||
// using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
// using ShardingCore.Exceptions;
|
||||
// using ShardingCore.Extensions;
|
||||
// using ShardingCore.Sharding.Abstractions;
|
||||
// using System;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Linq;
|
||||
// using System.Reflection;
|
||||
// using ShardingCore.Core.EntityMetadatas;
|
||||
// using ShardingCore.Core.TrackerManagers;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
//
|
||||
// namespace ShardingCore
|
||||
// {
|
||||
// /*
|
||||
// * @Author: xjm
|
||||
// * @Description:
|
||||
// * @Date: Saturday, 02 January 2021 19:37:27
|
||||
// * @Email: 326308290@qq.com
|
||||
// */
|
||||
// /// <summary>
|
||||
// /// 分片容器全局唯一提供静态依赖注入<code>IServiceProvider</code>
|
||||
// /// </summary>
|
||||
// public class ShardingContainer
|
||||
// {
|
||||
// private ShardingContainer()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private static IServiceProvider serviceProvider;
|
||||
//
|
||||
// public static IServiceProvider ServiceProvider
|
||||
// {
|
||||
// get { return serviceProvider ?? throw new ShardingCoreInvalidOperationException("sharding core not start"); }
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 静态注入
|
||||
// /// </summary>
|
||||
// /// <param name="services"></param>
|
||||
// public static void SetServices(IServiceProvider services)
|
||||
// {
|
||||
// if (serviceProvider == null)
|
||||
// serviceProvider = services;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 获取服务
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <returns></returns>
|
||||
// public static T GetService<T>()
|
||||
// {
|
||||
// return ServiceProvider.GetService<T>();
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 获取服务集合
|
||||
// /// </summary>
|
||||
// /// <typeparam name="T"></typeparam>
|
||||
// /// <returns></returns>
|
||||
// public static IEnumerable<T> GetServices<T>()
|
||||
// {
|
||||
// return ServiceProvider.GetServices<T>();
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 根据类型获取服务
|
||||
// /// </summary>
|
||||
// /// <param name="serviceType"></param>
|
||||
// /// <returns></returns>
|
||||
// public static object GetService(Type serviceType)
|
||||
// {
|
||||
// return ServiceProvider.GetService(serviceType);
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取的
|
||||
// /// </summary>
|
||||
// /// <param name="serviceType"></param>
|
||||
// /// <returns></returns>
|
||||
// /// <exception cref="ArgumentException"></exception>
|
||||
// public static object CreateInstance(Type serviceType)
|
||||
// {
|
||||
// var constructors
|
||||
// = serviceType.GetTypeInfo().DeclaredConstructors
|
||||
// .Where(c => !c.IsStatic && c.IsPublic)
|
||||
// .ToArray();
|
||||
//
|
||||
// if (constructors.Length != 1)
|
||||
// {
|
||||
// throw new ArgumentException(
|
||||
// $"type :[{serviceType}] found more than one declared constructor ");
|
||||
// }
|
||||
// var @params = constructors[0].GetParameters().Select(x => ServiceProvider.GetService(x.ParameterType))
|
||||
// .ToArray();
|
||||
// return Activator.CreateInstance(serviceType, @params);
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 创建一个没有依赖注入的对象,但是对象的构造函数参数是已经可以通过依赖注入获取并且也存在自行传入的参数,优先判断自行传入的参数
|
||||
// /// </summary>
|
||||
// /// <param name="serviceType"></param>
|
||||
// /// <param name="args"></param>
|
||||
// /// <returns></returns>
|
||||
// /// <exception cref="ArgumentException"></exception>
|
||||
// public static object CreateInstanceWithInputParams(Type serviceType, params object[] args)
|
||||
// {
|
||||
// var constructors
|
||||
// = serviceType.GetTypeInfo().DeclaredConstructors
|
||||
// .Where(c => !c.IsStatic && c.IsPublic)
|
||||
// .ToArray();
|
||||
//
|
||||
// if (constructors.Length != 1)
|
||||
// {
|
||||
// throw new ArgumentException(
|
||||
// $"type :[{serviceType}] found more than one declared constructor ");
|
||||
// }
|
||||
//
|
||||
// var argIsNotEmpty = args.IsNotEmpty();
|
||||
// var @params = constructors[0].GetParameters().Select(x =>
|
||||
// {
|
||||
// if (argIsNotEmpty)
|
||||
// {
|
||||
// var arg = args.FirstOrDefault(o => o.GetType() == x.ParameterType);
|
||||
// if (arg != null)
|
||||
// return arg;
|
||||
// }
|
||||
// return ServiceProvider.GetService(x.ParameterType);
|
||||
// })
|
||||
// .ToArray();
|
||||
// return Activator.CreateInstance(serviceType, @params);
|
||||
// }
|
||||
//
|
||||
// //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 (IShardingEntityConfigOptions<TShardingDbContext>)GetRequiredShardingEntityConfigOption(typeof(TShardingDbContext));
|
||||
// }
|
||||
// public static IShardingEntityConfigOptions GetRequiredShardingEntityConfigOption(Type 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> GetRequiredCurrentVirtualDataSource<TShardingDbContext>()
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
// return GetRequiredVirtualDataSourceManager<TShardingDbContext>().GetCurrentVirtualDataSource() ?? throw new InvalidOperationException("cant resolve CurrentVirtualDataSource");
|
||||
// }
|
||||
// public static IVirtualDataSource GetRequiredCurrentVirtualDataSource(Type shardingDbContextType)
|
||||
// {
|
||||
// return GetRequiredVirtualDataSourceManager(shardingDbContextType).GetCurrentVirtualDataSource()??throw new InvalidOperationException("cant resolve CurrentVirtualDataSource");
|
||||
// }
|
||||
//
|
||||
// public static IEntityMetadataManager GetRequiredEntityMetadataManager(Type shardingDbContextType)
|
||||
// {
|
||||
// return (IEntityMetadataManager)ServiceProvider.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(shardingDbContextType));
|
||||
// }
|
||||
//
|
||||
// public static IEntityMetadataManager<TShardingDbContext> GetRequiredEntityMetadataManager<TShardingDbContext>()
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
// return (IEntityMetadataManager<TShardingDbContext>)GetRequiredEntityMetadataManager(typeof(TShardingDbContext));
|
||||
// }
|
||||
//
|
||||
// public static ITrackerManager GetTrackerManager(Type shardingDbContextType)
|
||||
// {
|
||||
// return (ITrackerManager)ServiceProvider.GetService(typeof(ITrackerManager<>).GetGenericType0(shardingDbContextType));
|
||||
// }
|
||||
//
|
||||
// public static IVirtualTableManager GetVirtualTableManager(Type shardingDbContextType)
|
||||
// {
|
||||
// return (IVirtualTableManager)ServiceProvider.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContextType));
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -37,6 +37,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Core\RuntimeModels" />
|
||||
<Folder Include="Sharding\Visitors\GroupBys" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in New Issue