优化ShardingConfigOption通过泛型方法获取而不是枚举,增加DbContextCollector收集器用来启动判断

This commit is contained in:
xuejiaming 2021-12-23 10:24:30 +08:00
parent d647dba4ce
commit 6f3ce998e4
19 changed files with 170 additions and 103 deletions

View File

@ -37,7 +37,7 @@ namespace ShardingCore.Bootstrapers
{ {
private readonly IEntityType _entityType; private readonly IEntityType _entityType;
private readonly string _virtualTableName; private readonly string _virtualTableName;
private readonly IShardingConfigOption _shardingConfigOption; private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
private readonly ITrackerManager<TShardingDbContext> _trackerManager; private readonly ITrackerManager<TShardingDbContext> _trackerManager;
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource; private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager; private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
@ -45,7 +45,7 @@ namespace ShardingCore.Bootstrapers
private readonly ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> _logger; private readonly ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> _logger;
public EntityMetadataInitializer(EntityMetadataEnsureParams entityMetadataEnsureParams public EntityMetadataInitializer(EntityMetadataEnsureParams entityMetadataEnsureParams
, IEnumerable<IShardingConfigOption> shardingConfigOptions, , IShardingConfigOption<TShardingDbContext> shardingConfigOption,
ITrackerManager<TShardingDbContext> trackerManager,IVirtualDataSource<TShardingDbContext> virtualDataSource,IVirtualTableManager<TShardingDbContext> virtualTableManager, ITrackerManager<TShardingDbContext> trackerManager,IVirtualDataSource<TShardingDbContext> virtualDataSource,IVirtualTableManager<TShardingDbContext> virtualTableManager,
IEntityMetadataManager<TShardingDbContext> entityMetadataManager, IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> logger ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> logger
@ -53,7 +53,7 @@ namespace ShardingCore.Bootstrapers
{ {
_entityType = entityMetadataEnsureParams.EntityType; _entityType = entityMetadataEnsureParams.EntityType;
_virtualTableName = entityMetadataEnsureParams.VirtualTableName; _virtualTableName = entityMetadataEnsureParams.VirtualTableName;
_shardingConfigOption = shardingConfigOptions.FirstOrDefault(o=>o.ShardingDbContextType==typeof(TShardingDbContext)); _shardingConfigOption = shardingConfigOption;
_trackerManager = trackerManager; _trackerManager = trackerManager;
_virtualDataSource = virtualDataSource; _virtualDataSource = virtualDataSource;
_virtualTableManager = virtualTableManager; _virtualTableManager = virtualTableManager;

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Jobs; using ShardingCore.Jobs;
using ShardingCore.Jobs.Abstaractions; using ShardingCore.Jobs.Abstaractions;
@ -16,13 +17,13 @@ namespace ShardingCore.Bootstrapers
*/ */
public class ShardingBootstrapper : IShardingBootstrapper public class ShardingBootstrapper : IShardingBootstrapper
{ {
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions; private readonly IEnumerable<IDbContextTypeCollector> _dbContextTypeCollectors;
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce(); private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
public ShardingBootstrapper(IServiceProvider serviceProvider) public ShardingBootstrapper(IServiceProvider serviceProvider,IEnumerable<IDbContextTypeCollector> dbContextTypeCollectors)
{ {
_dbContextTypeCollectors = dbContextTypeCollectors;
ShardingContainer.SetServices(serviceProvider); ShardingContainer.SetServices(serviceProvider);
_shardingConfigOptions = ShardingContainer.GetServices<IShardingConfigOption>();
} }
/// <summary> /// <summary>
/// Æô¶¯ /// Æô¶¯
@ -31,9 +32,9 @@ namespace ShardingCore.Bootstrapers
{ {
if (!_doOnlyOnce.IsUnDo()) if (!_doOnlyOnce.IsUnDo())
return; return;
foreach (var shardingConfigOption in _shardingConfigOptions) foreach (var dbContextTypeCollector in _dbContextTypeCollectors)
{ {
var instance = (IShardingDbContextBootstrapper)Activator.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(shardingConfigOption.ShardingDbContextType), shardingConfigOption); var instance = (IShardingDbContextBootstrapper)ShardingContainer.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(dbContextTypeCollector.ShardingDbContextType));
instance.Init(); instance.Init();
} }

View File

@ -54,27 +54,25 @@ namespace ShardingCore.Bootstrapers
/// </summary> /// </summary>
public class ShardingDbContextBootstrapper<TShardingDbContext> : IShardingDbContextBootstrapper where TShardingDbContext : DbContext, IShardingDbContext public class ShardingDbContextBootstrapper<TShardingDbContext> : IShardingDbContextBootstrapper where TShardingDbContext : DbContext, IShardingDbContext
{ {
private readonly IShardingConfigOption _shardingConfigOption; private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
private readonly IRouteTailFactory _routeTailFactory;
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource; private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager; private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
private readonly IShardingTableCreator<TShardingDbContext> _tableCreator;
private readonly IParallelTableManager<TShardingDbContext> _parallelTableManager; private readonly IParallelTableManager<TShardingDbContext> _parallelTableManager;
private readonly IDataSourceInitializer<TShardingDbContext> _dataSourceInitializer; private readonly IDataSourceInitializer<TShardingDbContext> _dataSourceInitializer;
private readonly ILogger<ShardingDbContextBootstrapper<TShardingDbContext>> _logger; private readonly Type _shardingDbContextType;
public ShardingDbContextBootstrapper(IShardingConfigOption shardingConfigOption) public ShardingDbContextBootstrapper(IShardingConfigOption<TShardingDbContext> shardingConfigOption,
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
IVirtualDataSource<TShardingDbContext> virtualDataSource,
IParallelTableManager<TShardingDbContext> parallelTableManager,
IDataSourceInitializer<TShardingDbContext> dataSourceInitializer)
{ {
_shardingConfigOption = shardingConfigOption; _shardingConfigOption = shardingConfigOption;
_routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>(); _shardingDbContextType = typeof(TShardingDbContext);
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>(); _entityMetadataManager = entityMetadataManager;
_entityMetadataManager = ShardingContainer.GetService<IEntityMetadataManager<TShardingDbContext>>(); _virtualDataSource= virtualDataSource;
_tableCreator = ShardingContainer.GetService<IShardingTableCreator<TShardingDbContext>>(); _parallelTableManager = parallelTableManager;
_virtualDataSource= ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>(); _dataSourceInitializer = dataSourceInitializer;
_parallelTableManager = ShardingContainer.GetService<IParallelTableManager<TShardingDbContext>>();
_dataSourceInitializer = ShardingContainer.GetService<IDataSourceInitializer<TShardingDbContext>>();
_logger = ShardingContainer.GetService<ILogger<ShardingDbContextBootstrapper<TShardingDbContext>>>();
} }
/// <summary> /// <summary>
/// 初始化 /// 初始化
@ -94,7 +92,7 @@ namespace ShardingCore.Bootstrapers
{ {
//var dataSourceName = _virtualDataSource.DefaultDataSourceName; //var dataSourceName = _virtualDataSource.DefaultDataSourceName;
using var context = using var context =
(DbContext)serviceScope.ServiceProvider.GetService(_shardingConfigOption.ShardingDbContextType); (DbContext)serviceScope.ServiceProvider.GetService(_shardingDbContextType);
foreach (var entity in context.Model.GetEntityTypes()) foreach (var entity in context.Model.GetEntityTypes())
{ {
@ -103,21 +101,9 @@ namespace ShardingCore.Bootstrapers
if (_shardingConfigOption.HasVirtualDataSourceRoute(entityType) || if (_shardingConfigOption.HasVirtualDataSourceRoute(entityType) ||
_shardingConfigOption.HasVirtualTableRoute(entityType)) _shardingConfigOption.HasVirtualTableRoute(entityType))
{ {
var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(typeof(TShardingDbContext), entityType); var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(_shardingDbContextType, entityType);
var constructors
= entityMetadataInitializerType.GetTypeInfo().DeclaredConstructors var entityMetadataInitializer = (IEntityMetadataInitializer)ShardingContainer.CreateInstanceWithInputParams(entityMetadataInitializerType, new EntityMetadataEnsureParams(entity));
.Where(c => !c.IsStatic && c.IsPublic)
.ToArray();
var @params = constructors[0].GetParameters().Select((o, i) =>
{
if (i == 0)
{
return new EntityMetadataEnsureParams( entity);
}
return ShardingContainer.GetService(o.ParameterType);
}).ToArray();
var entityMetadataInitializer = (IEntityMetadataInitializer)Activator.CreateInstance(entityMetadataInitializerType, @params);
entityMetadataInitializer.Initialize(); entityMetadataInitializer.Initialize();
} }
} }

View File

@ -16,12 +16,12 @@ namespace ShardingCore.Core.TrackerManagers
*/ */
public class TrackerManager<TShardingDbContext>: ITrackerManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext public class TrackerManager<TShardingDbContext>: ITrackerManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{ {
private readonly IShardingConfigOption _shardingConfigOption; private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
private readonly ISet<Type> _dbContextModels = new HashSet<Type>(); private readonly ISet<Type> _dbContextModels = new HashSet<Type>();
public TrackerManager(IEnumerable<IShardingConfigOption> shardingConfigOptions) public TrackerManager(IShardingConfigOption<TShardingDbContext> shardingConfigOption)
{ {
_shardingConfigOption = shardingConfigOptions.FirstOrDefault(o=>o.ShardingDbContextType==typeof(TShardingDbContext)); _shardingConfigOption = shardingConfigOption;
} }
public bool AddDbContextModel(Type entityType) public bool AddDbContextModel(Type entityType)
{ {

View File

@ -59,7 +59,8 @@ namespace ShardingCore.DIExtensions
public IServiceCollection End() public IServiceCollection End()
{ {
var services = _shardingCoreConfigBuilder.Services; var services = _shardingCoreConfigBuilder.Services;
services.AddSingleton<IShardingConfigOption, ShardingConfigOption<TShardingDbContext>>(sp => services.AddSingleton<IDbContextTypeCollector>(sp => new DbContextTypeCollector<TShardingDbContext>());
services.AddSingleton<IShardingConfigOption<TShardingDbContext>, ShardingConfigOption<TShardingDbContext>>(sp =>
_shardingCoreConfigBuilder.ShardingConfigOption); _shardingCoreConfigBuilder.ShardingConfigOption);

View File

@ -35,16 +35,15 @@ namespace ShardingCore.DynamicDataSources
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager; private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
private readonly IShardingTableCreator<TShardingDbContext> _tableCreator; private readonly IShardingTableCreator<TShardingDbContext> _tableCreator;
private readonly ILogger<DataSourceInitializer<TShardingDbContext>> _logger; private readonly ILogger<DataSourceInitializer<TShardingDbContext>> _logger;
private readonly IShardingConfigOption _shardingConfigOption; private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
public DataSourceInitializer(IEnumerable<IShardingConfigOption> shardingConfigOptions, public DataSourceInitializer(IShardingConfigOption<TShardingDbContext> shardingConfigOption,
IRouteTailFactory routeTailFactory, IVirtualTableManager<TShardingDbContext> virtualTableManager, IRouteTailFactory routeTailFactory, IVirtualTableManager<TShardingDbContext> virtualTableManager,
IEntityMetadataManager<TShardingDbContext> entityMetadataManager, IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
IShardingTableCreator<TShardingDbContext> shardingTableCreator, IShardingTableCreator<TShardingDbContext> shardingTableCreator,
IVirtualDataSource<TShardingDbContext> virtualDataSource, IVirtualDataSource<TShardingDbContext> virtualDataSource,
ILogger<DataSourceInitializer<TShardingDbContext>> logger) ILogger<DataSourceInitializer<TShardingDbContext>> logger)
{ {
_shardingConfigOption = _shardingConfigOption = shardingConfigOption;
shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == typeof(TShardingDbContext)) ?? throw new ArgumentNullException($"{nameof(IShardingConfigOption)} cant been registered {typeof(TShardingDbContext)}");
_routeTailFactory = routeTailFactory; _routeTailFactory = routeTailFactory;
_virtualTableManager = virtualTableManager; _virtualTableManager = virtualTableManager;
_entityMetadataManager = entityMetadataManager; _entityMetadataManager = entityMetadataManager;

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ReadWriteConfigurations; using ShardingCore.Sharding.ReadWriteConfigurations;
@ -83,21 +84,27 @@ namespace ShardingCore.Extensions
{ {
if (shardingDbContext is ISupportShardingReadWrite shardingReadWrite) if (shardingDbContext is ISupportShardingReadWrite shardingReadWrite)
{ {
var shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>(); var shardingDbContextType = shardingDbContext.GetType();
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(shardingDbContext.GetType()); var shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(shardingDbContextType);
if (shardingReadWriteContext != null) var useReadWrite=shardingConfigOption?.UseReadWrite ?? false;
if (useReadWrite)
{ {
if (shardingReadWriteContext.DefaultPriority > shardingReadWrite.ReadWriteSeparationPriority) var shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>();
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(shardingDbContextType);
if (shardingReadWriteContext != null)
{ {
return shardingReadWriteContext.DefaultReadEnable; if (shardingReadWriteContext.DefaultPriority > shardingReadWrite.ReadWriteSeparationPriority)
{
return shardingReadWriteContext.DefaultReadEnable;
}
else
{
return shardingReadWrite.ReadWriteSeparation;
}
} }
else
{
return shardingReadWrite.ReadWriteSeparation;
}
}
return shardingReadWrite.ReadWriteSeparation; return shardingReadWrite.ReadWriteSeparation;
}
} }
return false; return false;

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore
{
public interface IDbContextTypeCollector
{
Type ShardingDbContextType { get; }
}
public class DbContextTypeCollector<TShardingDbContext> : IDbContextTypeCollector
where TShardingDbContext : DbContext, IShardingDbContext
{
public DbContextTypeCollector()
{
ShardingDbContextType = typeof(TShardingDbContext);
}
public Type ShardingDbContextType { get; }
}
}

View File

@ -18,7 +18,6 @@ namespace ShardingCore
*/ */
public interface IShardingConfigOption public interface IShardingConfigOption
{ {
Type ShardingDbContextType { get;}
bool UseReadWrite { get; } bool UseReadWrite { get; }
bool HasVirtualTableRoute(Type entityType); bool HasVirtualTableRoute(Type entityType);

View File

@ -31,13 +31,16 @@ namespace ShardingCore.Sharding
{ {
_virtualDataSource=ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>(); _virtualDataSource=ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
_connectionStringManager = ShardingContainer.GetService<IConnectionStringManager<TShardingDbContext>>(); _connectionStringManager = ShardingContainer.GetService<IConnectionStringManager<TShardingDbContext>>();
_readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
_shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>(); _shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>();
_useReadWriteSeparation = _connectionStringManager is ReadWriteConnectionStringManager<TShardingDbContext>; _useReadWriteSeparation = _connectionStringManager is ReadWriteConnectionStringManager<TShardingDbContext>;
if (_readWriteOptions != null) if (_useReadWriteSeparation)
{ {
ReadWriteSeparationPriority = _readWriteOptions.ReadWritePriority; _readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
ReadWriteSeparation = _readWriteOptions.ReadWriteSupport; if (_readWriteOptions != null)
{
ReadWriteSeparationPriority = _readWriteOptions.ReadWritePriority;
ReadWriteSeparation = _readWriteOptions.ReadWriteSupport;
}
} }
} }

View File

@ -8,7 +8,7 @@ using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Sharding.ParallelTables namespace ShardingCore.Sharding.ParallelTables
{ {
internal interface IParallelTableManager<TShardingDbContext> : IParallelTableManager public interface IParallelTableManager<TShardingDbContext> : IParallelTableManager
where TShardingDbContext : DbContext, IShardingDbContext where TShardingDbContext : DbContext, IShardingDbContext
{ {

View File

@ -9,7 +9,7 @@ using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Sharding.ParallelTables namespace ShardingCore.Sharding.ParallelTables
{ {
internal sealed class ParallelTableManager<TShardingDbContext> : IParallelTableManager<TShardingDbContext> public sealed class ParallelTableManager<TShardingDbContext> : IParallelTableManager<TShardingDbContext>
where TShardingDbContext : DbContext, IShardingDbContext where TShardingDbContext : DbContext, IShardingDbContext
{ {
private readonly ISet<ParallelTableGroupNode> _parallelTableConfigs = new HashSet<ParallelTableGroupNode>(); private readonly ISet<ParallelTableGroupNode> _parallelTableConfigs = new HashSet<ParallelTableGroupNode>();

View File

@ -20,6 +20,10 @@ namespace ShardingCore.Sharding.ShardingExecutors.Abstractions
Type GetShardingDbContextType(); Type GetShardingDbContextType();
QueryCompilerExecutor GetQueryCompilerExecutor(); QueryCompilerExecutor GetQueryCompilerExecutor();
bool IsEnumerableQuery(); bool IsEnumerableQuery();
bool IsParallelQuery(); /// <summary>
/// 当前是否读写分离走读库(包括是否启用读写分离和是否当前的dbcontext启用了读库查询)
/// </summary>
/// <returns></returns>
bool CurrentQueryReadConnection();
} }
} }

View File

@ -92,9 +92,9 @@ namespace ShardingCore.Sharding.ShardingExecutors
{ {
return _queryCompilerContext.GetShardingDbContextType(); return _queryCompilerContext.GetShardingDbContextType();
} }
public bool IsParallelQuery() public bool CurrentQueryReadConnection()
{ {
return _queryCompilerContext.IsParallelQuery(); return _queryCompilerContext.CurrentQueryReadConnection();
} }
public QueryCompilerExecutor GetQueryCompilerExecutor() public QueryCompilerExecutor GetQueryCompilerExecutor()
@ -105,7 +105,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
if (hasQueryCompilerExecutor.Value) if (hasQueryCompilerExecutor.Value)
{ {
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>(); var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), IsParallelQuery(), routeTailFactory.Create(_tableRouteResults.First())); var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First()));
_queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression()); _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression());
} }
} }

View File

@ -36,8 +36,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
_queryExpression = queryExpression; _queryExpression = queryExpression;
_entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType)); _entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType));
_shardingConfigOption = ShardingContainer.GetServices<IShardingConfigOption>() _shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(_shardingDbContextType);
.FirstOrDefault(o => o.ShardingDbContextType == _shardingDbContextType);
} }
public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression) public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression)
@ -70,7 +69,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
return _shardingDbContextType; return _shardingDbContextType;
} }
public bool IsParallelQuery() public bool CurrentQueryReadConnection()
{ {
return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation(); return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation();
} }
@ -84,7 +83,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService( var virtualDataSource = (IVirtualDataSource)ShardingContainer.GetService(
typeof(IVirtualDataSource<>).GetGenericType0(_shardingDbContextType)); typeof(IVirtualDataSource<>).GetGenericType0(_shardingDbContextType));
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>(); var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
var dbContext = _shardingDbContext.GetDbContext(virtualDataSource.DefaultDataSourceName, IsParallelQuery(), routeTailFactory.Create(string.Empty)); var dbContext = _shardingDbContext.GetDbContext(virtualDataSource.DefaultDataSourceName, CurrentQueryReadConnection(), routeTailFactory.Create(string.Empty));
_queryCompilerExecutor = new QueryCompilerExecutor(dbContext, _queryExpression); _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, _queryExpression);
} }
} }

View File

@ -100,26 +100,9 @@ namespace ShardingCore.Sharding
typeof(ITrackerManager<>).GetGenericType0(mergeQueryCompilerContext.GetShardingDbContextType())); typeof(ITrackerManager<>).GetGenericType0(mergeQueryCompilerContext.GetShardingDbContextType()));
_shardingComparer = (IShardingComparer)ShardingContainer.GetService(typeof(IShardingComparer<>).GetGenericType0(_shardingDbContext.GetType())); _shardingComparer = (IShardingComparer)ShardingContainer.GetService(typeof(IShardingComparer<>).GetGenericType0(_shardingDbContext.GetType()));
_shardingConfigOption = ShardingContainer.GetServices<IShardingConfigOption>() _shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(mergeQueryCompilerContext.GetShardingDbContextType());
.FirstOrDefault(o => o.ShardingDbContextType == mergeQueryCompilerContext.GetShardingDbContextType());
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>(); _parallelDbContexts = new ConcurrentDictionary<DbContext, object>();
//RouteResults = _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
} }
//public StreamMergeContext(IQueryable<T> source,IEnumerable<TableRouteResult> routeResults,
// IShardingParallelDbContextFactory shardingParallelDbContextFactory,IShardingScopeFactory shardingScopeFactory)
//{
// _shardingParallelDbContextFactory = shardingParallelDbContextFactory;
// _shardingScopeFactory = shardingScopeFactory;
// _source = source;
// RouteResults = routeResults;
// var reWriteResult = new ReWriteEngine<T>(source).ReWrite();
// Skip = reWriteResult.Skip;
// Take = reWriteResult.Take;
// Orders = reWriteResult.Orders ?? Enumerable.Empty<PropertyOrder>();
// SelectContext = reWriteResult.SelectContext;
// GroupByContext = reWriteResult.GroupByContext;
// _reWriteSource = reWriteResult.ReWriteQueryable;
//}
public void ReSetOrders(IEnumerable<PropertyOrder> orders) public void ReSetOrders(IEnumerable<PropertyOrder> orders)
{ {
Orders = orders; Orders = orders;
@ -250,7 +233,7 @@ namespace ShardingCore.Sharding
/// <returns></returns> /// <returns></returns>
public bool IsParallelQuery() public bool IsParallelQuery()
{ {
return !_shardingConfigOption.AutoTrackEntity || MergeQueryCompilerContext.IsCrossTable() || MergeQueryCompilerContext.IsParallelQuery(); return !_shardingConfigOption.AutoTrackEntity || MergeQueryCompilerContext.IsCrossTable() || MergeQueryCompilerContext.CurrentQueryReadConnection();
} }
/// <summary> /// <summary>

View File

@ -107,9 +107,6 @@ namespace ShardingCore
ReadConnStringGetStrategy = readConnStringGetStrategy; ReadConnStringGetStrategy = readConnStringGetStrategy;
} }
public Type ShardingDbContextType => typeof(TShardingDbContext);
/// <summary> /// <summary>
/// 添加分表路由 /// 添加分表路由
/// </summary> /// </summary>

View File

@ -1,13 +1,12 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.Exceptions; using ShardingCore.Exceptions;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace ShardingCore namespace ShardingCore
{ {
@ -51,6 +50,71 @@ namespace ShardingCore
{ {
return ServiceProvider.GetService(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));
}
} }
} }

View File

@ -28,15 +28,14 @@ namespace ShardingCore.TableCreator
{ {
private readonly ILogger<ShardingTableCreator<TShardingDbContext>> _logger; private readonly ILogger<ShardingTableCreator<TShardingDbContext>> _logger;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IShardingConfigOption _shardingConfigOption; private readonly IShardingConfigOption<TShardingDbContext> _shardingConfigOption;
private readonly IRouteTailFactory _routeTailFactory; private readonly IRouteTailFactory _routeTailFactory;
public ShardingTableCreator(ILogger<ShardingTableCreator<TShardingDbContext>> logger, IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions, IRouteTailFactory routeTailFactory) public ShardingTableCreator(ILogger<ShardingTableCreator<TShardingDbContext>> logger, IServiceProvider serviceProvider, IShardingConfigOption<TShardingDbContext> shardingConfigOption, IRouteTailFactory routeTailFactory)
{ {
_logger = logger; _logger = logger;
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
_shardingConfigOption = shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == typeof(TShardingDbContext)) _shardingConfigOption = shardingConfigOption;
?? throw new ArgumentNullException(typeof(TShardingDbContext).FullName);
_routeTailFactory = routeTailFactory; _routeTailFactory = routeTailFactory;
} }