优化部分代码还不能编译打算移除掉virtualtablemanager和virtualtable简化概念

This commit is contained in:
xuejiaming 2022-06-28 23:16:50 +08:00
parent b38bf2b236
commit 3b4da3a7ef
38 changed files with 230 additions and 138 deletions

View File

@ -1,5 +1,6 @@
using Sample.MySql.Domain.Entities;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.VirtualRoutes.Mods;
namespace Sample.MySql.Shardings
@ -20,5 +21,6 @@ namespace Sample.MySql.Shardings
{
}
}
}

View File

@ -156,7 +156,7 @@ namespace ShardingCore.Bootstrappers
}
private void InitVirtualTable(IVirtualTable virtualTable)
{
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
foreach (var tail in virtualTable.GetVirtualRoute().GetTails())
{
var defaultPhysicTable = new DefaultPhysicTable(virtualTable, tail);
virtualTable.AddPhysicTable(defaultPhysicTable);

View File

@ -20,7 +20,7 @@ namespace ShardingCore.Core.DbContextCreator
/// Author: xjm
/// Created: 2022/4/2 21:15:09
/// Email: 326308290@qq.com
public class ActivatorDbContextCreator<TShardingDbContext>: IDbContextCreator<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
public class ActivatorDbContextCreator<TShardingDbContext>: IDbContextCreator where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly Func<ShardingDbContextOptions, DbContext> _creator;
public ActivatorDbContextCreator()

View File

@ -9,6 +9,7 @@ using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ParallelTables;
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
@ -17,6 +18,7 @@ namespace ShardingCore.Core
public interface IShardingRuntimeContext
{
IShardingCompilerExecutor GetShardingCompilerExecutor();
IShardingReadWriteManager GetShardingReadWriteManager();
ITrackerManager GetTrackerManager();
IParallelTableManager GetParallelTableManager();

View File

@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.QueryRouteManagers.Abstractions
{
@ -15,7 +18,7 @@ namespace ShardingCore.Core.QueryRouteManagers.Abstractions
/// </summary>
public interface ITableRouteAssert
{
void Assert(List<IPhysicTable> allPhysicTables, List<IPhysicTable> resultPhysicTables);
void Assert(DataSourceRouteResult dataSourceRouteResult,List<string> tails, List<ShardingRouteUnit> shardingRouteUnits);
}
public interface ITableRouteAssert<T> : ITableRouteAssert where T : class

View File

@ -19,11 +19,11 @@ using ShardingCore.Sharding.ShardingComparision.Abstractions;
namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
{
public class ShardingConfigBuilder
public class ShardingConfigBuilder<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
public ShardingCoreConfigBuilder ShardingCoreConfigBuilder { get; }
public ShardingCoreConfigBuilder<TShardingDbContext> ShardingCoreConfigBuilder { get; }
public ShardingConfigBuilder(ShardingCoreConfigBuilder shardingCoreConfigBuilder)
public ShardingConfigBuilder(ShardingCoreConfigBuilder<TShardingDbContext> shardingCoreConfigBuilder)
{
ShardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
@ -36,7 +36,7 @@ namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ShardingCoreConfigException"></exception>
/// <exception cref="ArgumentException"></exception>
public ShardingConfigBuilder AddConfig(Action<ShardingConfigOptions> shardingGlobalConfigOptionsConfigure)
public ShardingConfigBuilder<TShardingDbContext> AddConfig(Action<ShardingConfigOptions> shardingGlobalConfigOptionsConfigure)
{
var shardingGlobalConfigOptions = new ShardingConfigOptions();
shardingGlobalConfigOptionsConfigure?.Invoke(shardingGlobalConfigOptions);

View File

@ -20,7 +20,7 @@ namespace ShardingCore.DIExtensions
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingCoreConfigBuilder
public class ShardingCoreConfigBuilder<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
public IServiceCollection Services { get; }

View File

@ -13,7 +13,9 @@ using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.ShardingEnumerableQueries;
using ShardingCore.Core.VirtualDatabase;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Sharding.EntityQueryConfigurations;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualTables
{
@ -79,7 +81,7 @@ namespace ShardingCore.Core.VirtualTables
return _physicTables.Keys.ToList();
}
public List<IPhysicTable> RouteTo(ShardingTableRouteConfig tableRouteConfig)
public List<ISqlRouteUnit> RouteTo(DataSourceRouteResult dataSourceRouteResult,ShardingTableRouteConfig tableRouteConfig)
{
var route = _virtualTableRoute;
if (tableRouteConfig.UseQueryable())

View File

@ -5,8 +5,10 @@ using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualDatabase;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Sharding.EntityQueryConfigurations;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
using ShardingCore.Sharding.PaginationConfigurations;
namespace ShardingCore.Core.VirtualTables
@ -49,9 +51,10 @@ namespace ShardingCore.Core.VirtualTables
/// <summary>
/// 路由到具体的物理表 which physic table route
/// </summary>
/// <param name="dataSourceRouteResult"></param>
/// <param name="tableRouteConfig"></param>
/// <returns></returns>
List<IPhysicTable> RouteTo(ShardingTableRouteConfig tableRouteConfig);
List<ISqlRouteUnit> RouteTo(DataSourceRouteResult dataSourceRouteResult,ShardingTableRouteConfig tableRouteConfig);
/// <summary>
/// 添加物理表 add physic table

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
namespace ShardingCore.Core.VirtualRoutes.Abstractions
{
public interface ITableRouteManager
{
bool HasRoute(Type entityType);
IVirtualTableRoute GetRoute(Type entityType);
List<IVirtualTableRoute> GetRoutes();
}
}

View File

@ -1,11 +0,0 @@
using System.Linq;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.Abstracttions
{
// public interface IShardingRoute
// {
// ISqlRouteUnit RouteTo(IQueryable queryable);
// }
}

View File

@ -0,0 +1,31 @@
using System;
namespace ShardingCore.Core.VirtualRoutes
{
public sealed class ShardingRouteUnit
{
public ShardingRouteUnit(string dataSourceName, string tail)
{
DataSourceName = dataSourceName;
Tail = tail;
}
public string DataSourceName { get; }
public string Tail { get;}
private bool Equals(ShardingRouteUnit other)
{
return DataSourceName == other.DataSourceName && Tail == other.Tail;
}
public override bool Equals(object obj)
{
return ReferenceEquals(this, obj) || obj is ShardingRouteUnit other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(DataSourceName, Tail);
}
}
}

View File

@ -7,8 +7,10 @@ using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.QueryRouteManagers;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
{
@ -35,12 +37,21 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
/// 启用断言路由
/// </summary>
protected virtual bool EnableAssertRoute => false;
public override List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable,bool isQuery)
/// <summary>
/// 路由是否忽略数据源
/// </summary>
protected virtual bool RouteIgnoreDataSource => true;
/// <summary>
/// 路由数据源和表后缀连接符
/// </summary>
protected virtual string RouteSeparator => ".";
public override List<ShardingRouteUnit> RouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable,bool isQuery)
{
if (!isQuery)
{
//后拦截器
return DoRouteWithPredicate(allPhysicTables, queryable);
return DoRouteWithPredicate(dataSourceRouteResult, queryable);
}
//强制路由不经过断言
if (EnableHintRoute)
@ -49,47 +60,49 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
{
if (CurrentShardingRouteContext.TryGetMustTail<T>(out HashSet<string> mustTails) && mustTails.IsNotEmpty())
{
var physicTables = allPhysicTables.Where(o => mustTails.Contains(o.Tail)).ToList();
if (physicTables.IsEmpty()||physicTables.Count!=mustTails.Count)
var filterTails = GetTails().Where(o => mustTails.Contains(o)).ToList();
if (filterTails.IsEmpty()||filterTails.Count!=mustTails.Count)
throw new ShardingCoreException(
$" sharding route must error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",mustTails)}]");
return physicTables;
var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new ShardingRouteUnit(dataSourceName,tail))).ToList();
return shardingRouteUnits;
}
if (CurrentShardingRouteContext.TryGetHintTail<T>(out HashSet<string> hintTails) && hintTails.IsNotEmpty())
{
var physicTables = allPhysicTables.Where(o => hintTails.Contains(o.Tail)).ToList();
if (physicTables.IsEmpty()||physicTables.Count!=hintTails.Count)
var filterTails = GetTails().Where(o => hintTails.Contains(o)).ToList();
if (filterTails.IsEmpty()||filterTails.Count!=hintTails.Count)
throw new ShardingCoreException(
$" sharding route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",hintTails)}]");
return GetFilterTableNames(allPhysicTables, physicTables);
var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new ShardingRouteUnit(dataSourceName,tail))).ToList();
return GetFilterTableTails(dataSourceRouteResult, shardingRouteUnits);
}
}
}
var filterPhysicTables = DoRouteWithPredicate(allPhysicTables,queryable);
return GetFilterTableNames(allPhysicTables, filterPhysicTables);
var filterPhysicTables = DoRouteWithPredicate(dataSourceRouteResult,queryable);
return GetFilterTableTails(dataSourceRouteResult, filterPhysicTables);
}
/// <summary>
/// 判断是调用全局过滤器还是调用内部断言
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="filterPhysicTables"></param>
/// <param name="dataSourceRouteResult"></param>
/// <param name="shardingRouteUnits"></param>
/// <returns></returns>
private List<IPhysicTable> GetFilterTableNames(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
private List<ShardingRouteUnit> GetFilterTableTails(DataSourceRouteResult dataSourceRouteResult, List<ShardingRouteUnit> shardingRouteUnits)
{
if (UseAssertRoute)
{
//最后处理断言
ProcessAssertRoutes(allPhysicTables, filterPhysicTables);
return filterPhysicTables;
ProcessAssertRoutes(dataSourceRouteResult, shardingRouteUnits);
return shardingRouteUnits;
}
else
{
//后拦截器
return AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
return AfterShardingRouteUnitFilter(dataSourceRouteResult, shardingRouteUnits);
}
}
@ -98,7 +111,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
out ICollection<ITableRouteAssert> routeAsserts) &&
routeAsserts.IsNotEmpty();
private void ProcessAssertRoutes(List<IPhysicTable> allPhysicTables,List<IPhysicTable> filterPhysicTables)
private void ProcessAssertRoutes(DataSourceRouteResult dataSourceRouteResult,List<ShardingRouteUnit> shardingRouteUnits)
{
if (UseAssertRoute)
{
@ -106,24 +119,33 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
{
foreach (var routeAssert in routeAsserts)
{
routeAssert.Assert(allPhysicTables, filterPhysicTables);
routeAssert.Assert(dataSourceRouteResult,GetTails(), shardingRouteUnits);
}
}
}
}
protected abstract List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
protected abstract List<ShardingRouteUnit> DoRouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable);
/// <summary>
/// 物理表过滤后
/// </summary>
/// <param name="allPhysicTables">所有的物理表</param>
/// <param name="filterPhysicTables">过滤后的物理表</param>
/// <param name="dataSourceRouteResult">所有的数据源</param>
/// <param name="shardingRouteUnits">所有的物理表</param>
/// <returns></returns>
protected virtual List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
protected virtual List<ShardingRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<ShardingRouteUnit> shardingRouteUnits)
{
return filterPhysicTables;
return shardingRouteUnits;
}
protected string FormatTableRouteWithDataSource(string dataSourceName, string tableTail)
{
if (RouteIgnoreDataSource)
{
return tableTail;
}
return $"{dataSourceName}{RouteSeparator}{tableTail}";
}
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
{
@ -18,16 +19,27 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
*/
public abstract class AbstractShardingOperatorVirtualTableRoute<TEntity, TKey> : AbstractShardingFilterVirtualTableRoute<TEntity, TKey> where TEntity : class
{
protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
/// <summary>
///
/// </summary>
/// <param name="dataSourceRouteResult"></param>
/// <param name="allPhysicTables"></param>
/// <param name="queryable"></param>
/// <returns></returns>
protected override List<ShardingRouteUnit> DoRouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable)
{
//获取路由后缀表达式
var routeParseExpression = ShardingUtil.GetRouteParseExpression(queryable, EntityMetadata, GetRouteFilter,true);
//表达式缓存编译
// var filter =CachingCompile(routeParseExpression);
var filter =routeParseExpression.GetRoutePredicate();
//通过编译结果进行过滤
var physicTables = allPhysicTables.Where(o => filter(o.Tail)).ToList();
return physicTables;
var sqlRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>
GetTails()
.Where(o=>filter(FormatTableRouteWithDataSource(dataSourceName,o)))
.Select(tail=>new ShardingRouteUnit(dataSourceName,tail))
).ToList();
return sqlRouteUnits;
}
@ -60,19 +72,23 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
throw new NotImplementedException(shardingPropertyName);
}
public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
public override ShardingRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey)
{
if (dataSourceRouteResult.IntersectDataSources.Count !=1)
{
throw new ShardingCoreException($"more than one route match data source:{string.Join(",", dataSourceRouteResult.IntersectDataSources)}");
}
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
if (physicTables.IsEmpty())
var filterTails = GetTails().Where(o => o== shardingKeyToTail).ToList();
if (filterTails.IsEmpty())
{
throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", allPhysicTables.Select(o=>o.EntityType))}]");
throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", filterTails)}]");
}
if (physicTables.Count > 1)
throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.EntityType}]"))}");
return physicTables[0];
if (filterTails.Count > 1)
throw new ShardingCoreException($"more than one route match table:{string.Join(",", filterTails)}");
return new ShardingRouteUnit(dataSourceRouteResult.IntersectDataSources.First(), filterTails[0]);
}
}

View File

@ -6,7 +6,9 @@ using ShardingCore.Sharding.MergeEngines.ParallelControl;
using ShardingCore.Sharding.PaginationConfigurations;
using System.Collections.Generic;
using System.Linq;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Sharding.EntityQueryConfigurations;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
{
@ -43,24 +45,24 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
/// <summary>
/// 根据表达式路由
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="dataSourceRouteResult"></param>
/// <param name="queryable"></param>
/// <param name="isQuery"></param>
/// <returns></returns>
public abstract List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable,bool isQuery);
public abstract List<ShardingRouteUnit> RouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable,bool isQuery);
/// <summary>
/// 根据值路由
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="dataSourceRouteResult"></param>
/// <param name="shardingKey"></param>
/// <returns></returns>
public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey);
public abstract ShardingRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey);
/// <summary>
/// 返回数据库现有的尾巴
/// </summary>
/// <returns></returns>
public abstract List<string> GetAllTails();
public abstract List<string> GetTails();
/// <summary>
/// 配置分表的一些信息

View File

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Sharding.EntityQueryConfigurations;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
using ShardingCore.Sharding.PaginationConfigurations;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes
@ -25,25 +27,25 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
/// <summary>
/// 根据查询条件路由返回物理表
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="dataSourceRouteResult"></param>
/// <param name="queryable"></param>
/// <param name="isQuery"></param>
/// <returns></returns>
List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables,IQueryable queryable,bool isQuery);
List<ShardingRouteUnit> RouteWithPredicate(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,bool isQuery);
/// <summary>
/// 根据值进行路由
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="dataSourceRouteResult"></param>
/// <param name="shardingKey"></param>
/// <returns></returns>
IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey);
ShardingRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey);
/// <summary>
/// 获取所有的目前数据库存在的尾巴,仅启动时调用
/// get all tails in the db
/// </summary>
/// <returns></returns>
List<string> GetAllTails();
List<string> GetTails();
}

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{
@ -14,6 +15,6 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
public interface ITableRouteRuleEngine
{
IEnumerable<TableRouteResult> Route(TableRouteRuleContext tableRouteRuleContext);
ShardingRouteUnit[] Route(TableRouteRuleContext tableRouteRuleContext);
}
}

View File

@ -4,6 +4,7 @@ using System.Linq;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{
@ -16,11 +17,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
public interface ITableRouteRuleEngineFactory
{
//TableRouteRuleContext CreateContext(IQueryable queryable);
IEnumerable<TableRouteResult> Route(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,Dictionary<Type,IQueryable> queryEntities);
ISqlRouteUnit[] Route(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,Dictionary<Type,IQueryable> queryEntities);
//IEnumerable<TableRouteResult> Route(TableRouteRuleContext ruleContext);
}
public interface ITableRouteRuleEngineFactory<TShardingDbContext> : ITableRouteRuleEngineFactory
where TShardingDbContext : DbContext, IShardingDbContext
{
}
}

View File

@ -15,21 +15,22 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
*/
public class TableRouteResult:IPrint
{
public TableRouteResult(IEnumerable<IPhysicTable> replaceTables, Type shardingDbContextType)
public TableRouteResult(List<IPhysicTable> replaceTables)
{
ShardingDbContextType = shardingDbContextType;
ReplaceTables = replaceTables.ToHashSet();
HasDifferentTail = ReplaceTables.IsNotEmpty() && ReplaceTables.GroupBy(o => o.Tail).Count() != 1;
}
public TableRouteResult(IPhysicTable replaceTable):this(new List<IPhysicTable>(){replaceTable})
{
}
public ISet<IPhysicTable> ReplaceTables { get; }
public bool HasDifferentTail { get; }
public Type ShardingDbContextType { get; }
protected bool Equals(TableRouteResult other)
{
return Equals(ReplaceTables, other.ReplaceTables) && Equals(ShardingDbContextType, other.ShardingDbContextType);
return ReplaceTables.SequenceEqual(other.ReplaceTables);
}
public override bool Equals(object obj)
@ -48,7 +49,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
public override int GetHashCode()
{
return HashCode.Combine(ReplaceTables, ShardingDbContextType);
return HashCode.Combine(ReplaceTables);
}
#endif

View File

@ -6,10 +6,12 @@ using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.ShardingDatabaseProviders;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.Abstractions;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
@ -22,20 +24,22 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
*/
public class TableRouteRuleEngine : ITableRouteRuleEngine
{
private readonly ITableRouteManager _tableRouteManager;
private readonly IVirtualTableManager _virtualTableManager;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IShardingDatabaseProvider _shardingDatabaseProvider;
public TableRouteRuleEngine(IVirtualTableManager virtualTableManager,IEntityMetadataManager entityMetadataManager,IShardingDatabaseProvider shardingDatabaseProvider)
public TableRouteRuleEngine(ITableRouteManager tableRouteManager,IVirtualTableManager virtualTableManager,IEntityMetadataManager entityMetadataManager,IShardingDatabaseProvider shardingDatabaseProvider)
{
_tableRouteManager = tableRouteManager;
_virtualTableManager = virtualTableManager;
_entityMetadataManager = entityMetadataManager;
_shardingDatabaseProvider = shardingDatabaseProvider;
}
public IEnumerable<TableRouteResult> Route(TableRouteRuleContext tableRouteRuleContext)
public ShardingRouteUnit[] Route(TableRouteRuleContext tableRouteRuleContext)
{
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
Dictionary<Type, ISet<ShardingRouteUnit>> routeMaps = new Dictionary<Type, ISet<ShardingRouteUnit>>();
var queryEntities = tableRouteRuleContext.QueryEntities;
@ -44,18 +48,18 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
var shardingEntity = shardingEntityKv.Key;
if (!_entityMetadataManager.IsShardingTable(shardingEntity))
continue;
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntity);
var virtualTableRoute = _tableRouteManager.GetRoute(shardingEntity);
var shardingRouteUnits = virtualTableRoute.RouteWithPredicate(tableRouteRuleContext.DataSourceRouteResult,(shardingEntityKv.Value ?? tableRouteRuleContext.Queryable),true);
var physicTables = virtualTable.RouteTo(new ShardingTableRouteConfig(shardingEntityKv.Value ?? tableRouteRuleContext.Queryable));
if (!routeMaps.ContainsKey(virtualTable))
if (!routeMaps.ContainsKey(shardingEntity))
{
routeMaps.Add(virtualTable, physicTables.ToHashSet());
routeMaps.Add(shardingEntity, shardingRouteUnits.ToHashSet());
}
else
{
foreach (var physicTable in physicTables)
foreach (var shardingRouteUnit in shardingRouteUnits)
{
routeMaps[virtualTable].Add(physicTable);
routeMaps[shardingEntity].Add(shardingRouteUnit);
}
}
}

View File

@ -6,6 +6,7 @@ using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{
@ -36,13 +37,13 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{
return new TableRouteRuleContext(dataSourceRouteResult,queryable,queryEntities);
}
public IEnumerable<TableRouteResult> Route(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
public ISqlRouteUnit[] Route(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
{
var ruleContext = CreateContext(dataSourceRouteResult,queryable, queryEntities);
return Route(ruleContext);
}
private IEnumerable<TableRouteResult> Route(TableRouteRuleContext ruleContext)
private ISqlRouteUnit[] Route(TableRouteRuleContext ruleContext)
{
return _tableRouteRuleEngine.Route(ruleContext);
}

View File

@ -100,7 +100,7 @@ namespace ShardingCore.DynamicDataSources
private void InitVirtualTable(IVirtualTable virtualTable)
{
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
foreach (var tail in virtualTable.GetVirtualRoute().GetTails())
{
var defaultPhysicTable = new DefaultPhysicTable(virtualTable, tail);
virtualTable.AddPhysicTable(defaultPhysicTable);

View File

@ -27,7 +27,7 @@ namespace ShardingCore.EFCores
{
_shardingDbContext = currentContext.Context as IShardingDbContext ??
throw new ShardingCoreException("db context operator is not IShardingDbContext");
_shardingCompilerExecutor = shardingRuntimeContext.GetService<IShardingCompilerExecutor>();
_shardingCompilerExecutor = shardingRuntimeContext.GetShardingCompilerExecutor();
}
public TResult Execute<TResult>(Expression query)

View File

@ -8,6 +8,7 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using ShardingCore.Core;
using ShardingCore.EFCores.OptionsExtensions;
using ShardingCore.Sharding.Abstractions;
@ -25,5 +26,10 @@ namespace ShardingCore.Extensions
var dbContext = (DbContext)shardingDbContext;
return dbContext.GetService<IDbContextServices>().ContextOptions.FindExtension<UnionAllMergeOptionsExtension>() is not null;
}
public static IShardingRuntimeContext GetShardingRuntimeContext(this IShardingDbContext shardingDbContext)
{
return ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>();
}
}
}

View File

@ -83,12 +83,11 @@ namespace ShardingCore.Extensions
{
if (shardingDbContext is ISupportShardingReadWrite shardingReadWrite)
{
var shardingDbContextType = shardingDbContext.GetType();
if (shardingDbContext.IsUseReadWriteSeparation())
{
var shardingRuntimeContext = ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>();
var shardingRuntimeContext = shardingDbContext.GetShardingRuntimeContext();
var shardingReadWriteManager =shardingRuntimeContext.GetService<IShardingReadWriteManager>();
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent(shardingDbContextType);
var shardingReadWriteContext = shardingReadWriteManager.GetCurrent();
if (shardingReadWriteContext != null)
{
if (shardingReadWriteContext.DefaultPriority > shardingReadWrite.ReadWriteSeparationPriority)

View File

@ -55,7 +55,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
_logger.LogLazyDebug(() => $"queryable combine after:{queryCombineResult.GetCombineQueryable().ShardingPrint()}");
var dataSourceRouteResult = dataSourceRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable(), prepareParseResult.GetShardingDbContext(), prepareParseResult.GetQueryEntities());
_logger.LogLazyDebug(() => $"{dataSourceRouteResult}");
var routeResults = tableRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable(), prepareParseResult.GetQueryEntities()).ToArray();
var routeResults = tableRouteRuleEngineFactory.Route(dataSourceRouteResult,queryCombineResult.GetCombineQueryable(), prepareParseResult.GetQueryEntities()).ToArray();
_logger.LogLazyDebug(() => $"table route results:{string.Join(","+Environment.NewLine,routeResults.Select(o=>o.GetPrintInfo()))}");
var mergeCombineCompilerContext = MergeQueryCompilerContext.Create(queryCompilerContext, queryCombineResult, dataSourceRouteResult,
routeResults);

View File

@ -17,21 +17,19 @@ namespace ShardingCore.TableCreator
/// <summary>
/// 创建表
/// </summary>
/// <param name="shardingDbContext"></param>
/// <param name="dataSourceName"></param>
/// <param name="tail"></param>
/// <typeparam name="T"></typeparam>
void CreateTable<T>(string dataSourceName, string tail) where T : class;
void CreateTable<T>(IShardingDbContext shardingDbContext,string dataSourceName, string tail) where T : class;
/// <summary>
/// 创建表
/// </summary>
/// <param name="shardingDbContext"></param>
/// <param name="dataSourceName"></param>
/// <param name="shardingEntityType"></param>
/// <param name="tail"></param>
/// <exception cref="ShardingCreateException"></exception>
void CreateTable(string dataSourceName, Type shardingEntityType, string tail);
}
public interface IShardingTableCreator<TShardingDbContext>: IShardingTableCreator where TShardingDbContext : DbContext, IShardingDbContext
{
void CreateTable(IShardingDbContext shardingDbContext,string dataSourceName, Type shardingEntityType, string tail);
}
}

View File

@ -20,58 +20,55 @@ namespace ShardingCore.TableCreator
* @Date: Monday, 21 December 2020 11:23:22
* @Email: 326308290@qq.com
*/
public class ShardingTableCreator<TShardingDbContext> : IShardingTableCreator<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
public class ShardingTableCreator : IShardingTableCreator
{
private static readonly ILogger<ShardingTableCreator<TShardingDbContext>> _logger =
InternalLoggerFactory.CreateLogger<ShardingTableCreator<TShardingDbContext>>();
private static readonly ILogger<ShardingTableCreator> _logger =
InternalLoggerFactory.CreateLogger<ShardingTableCreator>();
private readonly IServiceProvider _serviceProvider;
private readonly IShardingEntityConfigOptions<TShardingDbContext> _entityConfigOptions;
private readonly IShardingEntityConfigOptions _entityConfigOptions;
private readonly IRouteTailFactory _routeTailFactory;
public ShardingTableCreator(IServiceProvider serviceProvider, IShardingEntityConfigOptions<TShardingDbContext> entityConfigOptions, IRouteTailFactory routeTailFactory)
public ShardingTableCreator(IServiceProvider serviceProvider,
IShardingEntityConfigOptions entityConfigOptions, IRouteTailFactory routeTailFactory)
{
_serviceProvider = serviceProvider;
_entityConfigOptions = entityConfigOptions;
_routeTailFactory = routeTailFactory;
}
public void CreateTable<T>(string dataSourceName, string tail) where T : class
public void CreateTable<T>(IShardingDbContext shardingDbContext, string dataSourceName, string tail)
where T : class
{
CreateTable(dataSourceName, typeof(T), tail);
CreateTable(shardingDbContext, dataSourceName, typeof(T), tail);
}
/// <summary>
///
/// </summary>
/// <param name="shardingDbContext"></param>
/// <param name="dataSourceName"></param>
/// <param name="shardingEntityType"></param>
/// <param name="tail"></param>
public void CreateTable(string dataSourceName, Type shardingEntityType, string tail)
public void CreateTable(IShardingDbContext shardingDbContext, string dataSourceName, Type shardingEntityType,
string tail)
{
using (var serviceScope = _serviceProvider.CreateScope())
using (var context = shardingDbContext.GetDbContext(dataSourceName, false,
_routeTailFactory.Create(tail, false)))
{
using (var dbContext = serviceScope.ServiceProvider.GetService<TShardingDbContext>())
context.RemoveDbContextRelationModelSaveOnlyThatIsNamedType(shardingEntityType);
var databaseCreator = context.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
try
{
var shardingDbContext = (IShardingDbContext)dbContext;
using (var context = shardingDbContext.GetDbContext(dataSourceName, false,
_routeTailFactory.Create(tail, false)))
databaseCreator.CreateTables();
}
catch (Exception ex)
{
if (!_entityConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
{
context.RemoveDbContextRelationModelSaveOnlyThatIsNamedType(shardingEntityType);
var databaseCreator = context.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
try
{
databaseCreator.CreateTables();
}
catch (Exception ex)
{
if (!_entityConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
{
_logger.LogWarning(ex,
$"create table error entity name:[{shardingEntityType.Name}].");
throw new ShardingCoreException($" create table error :{ex.Message}", ex);
}
}
_logger.LogWarning(ex,
$"create table error entity name:[{shardingEntityType.Name}].");
throw new ShardingCoreException($" create table error :{ex.Message}", ex);
}
}
}

View File

@ -26,7 +26,7 @@ namespace ShardingCore.VirtualRoutes.Days
/// 然后会在启动的时候添加到 <see cref="IVirtualTable{TEntity}.AddPhysicTable(IPhysicTable physicTable)"/>
/// </summary>
/// <returns></returns>
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = GetBeginTime().Date;

View File

@ -16,7 +16,7 @@ namespace ShardingCore.VirtualRoutes.Days
public abstract class AbstractSimpleShardingDayKeyLongVirtualTableRoute<TEntity>:AbstractShardingTimeKeyLongVirtualTableRoute<TEntity> where TEntity:class
{
public abstract DateTime GetBeginTime();
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = GetBeginTime().Date;

View File

@ -43,7 +43,7 @@ namespace ShardingCore.VirtualRoutes.Mods
return Math.Abs(shardingKeyInt % Mod).ToString().PadLeft(TailLength,PaddingChar);
}
public override List<string> GetAllTails()
public override List<string> GetTails()
{
return Enumerable.Range(0, Mod).Select(o => o.ToString().PadLeft(TailLength, PaddingChar)).ToList();
}

View File

@ -55,7 +55,7 @@ namespace ShardingCore.VirtualRoutes.Mods
/// 获取对应类型在数据库中的所有后缀
/// </summary>
/// <returns></returns>
public override List<string> GetAllTails()
public override List<string> GetTails()
{
return Enumerable.Range(0, Mod).Select(o => o.ToString().PadLeft(TailLength, PaddingChar)).ToList();
}

View File

@ -16,7 +16,7 @@ namespace ShardingCore.VirtualRoutes.Months
public abstract class AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<TEntity> : AbstractShardingTimeKeyDateTimeVirtualTableRoute<TEntity> where TEntity : class
{
public abstract DateTime GetBeginTime();
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = ShardingCoreHelper.GetCurrentMonthFirstDay(GetBeginTime());

View File

@ -16,7 +16,7 @@ namespace ShardingCore.VirtualRoutes.Months
public abstract class AbstractSimpleShardingMonthKeyLongVirtualTableRoute<TEntity>:AbstractShardingTimeKeyLongVirtualTableRoute<TEntity> where TEntity:class
{
public abstract DateTime GetBeginTime();
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = ShardingCoreHelper.GetCurrentMonthFirstDay(GetBeginTime());

View File

@ -16,7 +16,7 @@ namespace ShardingCore.VirtualRoutes.Weeks
public abstract class AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute<TEntity> : AbstractShardingTimeKeyDateTimeVirtualTableRoute<TEntity> where TEntity : class
{
public abstract DateTime GetBeginTime();
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = GetBeginTime().Date;

View File

@ -23,7 +23,7 @@ namespace ShardingCore.VirtualRoutes.Weeks
{
public abstract DateTime GetBeginTime();
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = GetBeginTime().Date;

View File

@ -15,7 +15,7 @@ namespace ShardingCore.VirtualRoutes.Years
public abstract class AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute<TEntity> : AbstractShardingTimeKeyDateTimeVirtualTableRoute<TEntity> where TEntity : class
{
public abstract DateTime GetBeginTime();
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = GetBeginTime().Date;

View File

@ -24,7 +24,7 @@ namespace ShardingCore.VirtualRoutes.Years
/// 返回这个对象在数据库里面的所有表后缀
/// </summary>
/// <returns></returns>
public override List<string> GetAllTails()
public override List<string> GetTails()
{
var beginTime = GetBeginTime().Date;