From becb28595f7e0ef4954da93f411b269823eb1c80 Mon Sep 17 00:00:00 2001 From: xuejiaming <326308290@qq.com> Date: Thu, 26 Aug 2021 08:54:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=92=88=E5=AF=B9=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E8=B7=AF=E7=94=B1=E7=9A=84=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ValuesController.cs | 2 +- .../Shardings/SysUserModVirtualTableRoute.cs | 1 + ...AbstractShardingFilterVirtualTableRoute.cs | 5 + ...stractShardingOperatorVirtualTableRoute.cs | 1 + .../Abstractions/AbstractVirtualTableRoute.cs | 19 ++- .../Extensions/ShardingRouteExtension.cs | 114 +++++++++++++++++- ...leShardingModKeyStringVirtualTableRoute.cs | 22 +++- 7 files changed, 159 insertions(+), 5 deletions(-) diff --git a/samples/Sample.SqlServer/Controllers/ValuesController.cs b/samples/Sample.SqlServer/Controllers/ValuesController.cs index 5e0a1b71..7ee1122c 100644 --- a/samples/Sample.SqlServer/Controllers/ValuesController.cs +++ b/samples/Sample.SqlServer/Controllers/ValuesController.cs @@ -68,7 +68,7 @@ namespace Sample.SqlServer.Controllers using (_shardingRouteManager.CreateScope()) { - _shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); + _shardingRouteManager.Current.TryCreateOrAddMustTail("00"); var mod00s = await _defaultTableDbContext.Set().Skip(10).Take(11).ToListAsync(); } diff --git a/samples/Sample.SqlServer/Shardings/SysUserModVirtualTableRoute.cs b/samples/Sample.SqlServer/Shardings/SysUserModVirtualTableRoute.cs index d636f4cf..dda48bf6 100644 --- a/samples/Sample.SqlServer/Shardings/SysUserModVirtualTableRoute.cs +++ b/samples/Sample.SqlServer/Shardings/SysUserModVirtualTableRoute.cs @@ -17,6 +17,7 @@ namespace Sample.SqlServer.Shardings public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute { protected override bool EnableHintRoute => true; + protected override bool EnableAssertRoute => true; public SysUserModVirtualTableRoute() : base(2,3) { diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs index 133f8e5a..7bc34e54 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs @@ -18,6 +18,11 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions * @Ver: 1.0 * @Email: 326308290@qq.com */ + /// + /// 过滤虚拟路由用于处理强制路由、提示路由、路由断言 + /// + /// + /// public abstract class AbstractShardingFilterVirtualTableRoute : AbstractVirtualTableRoute where T : class, IShardingTable { public ShardingRouteContext CurrentShardingRouteContext => diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs index fe6d1292..e6b0cb8d 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs @@ -17,6 +17,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions */ public abstract class AbstractShardingOperatorVirtualTableRoute : AbstractShardingFilterVirtualTableRoute where T : class, IShardingTable { + protected override List DoRouteWithPredicate(List allPhysicTables, IQueryable queryable) { //获取所有需要路由的表后缀 diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs index 57db4ec0..ace2b114 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs @@ -18,19 +18,34 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions public abstract class AbstractVirtualTableRoute : IVirtualTableRoute where T : class, IShardingTable { public Type ShardingEntityType => typeof(T); + /// + /// 如何将分表字段转成对应的类型 + /// + /// + /// protected abstract TKey ConvertToShardingKey(object shardingKey); + /// + /// 如何将分表字段转成后缀 + /// + /// + /// public abstract string ShardingKeyToTail(object shardingKey); /// - /// 对外路由方法 + /// 根据表达式路由 /// /// /// /// public abstract List RouteWithPredicate(List allPhysicTables, IQueryable queryable); - + /// + /// 根据值路由 + /// + /// + /// + /// public abstract IPhysicTable RouteWithValue(List allPhysicTables, object shardingKeyValue); /// /// 返回数据库现有的尾巴 diff --git a/src/ShardingCore/Extensions/ShardingRouteExtension.cs b/src/ShardingCore/Extensions/ShardingRouteExtension.cs index 46efc748..c161a091 100644 --- a/src/ShardingCore/Extensions/ShardingRouteExtension.cs +++ b/src/ShardingCore/Extensions/ShardingRouteExtension.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using ShardingCore.Core; using ShardingCore.Core.QueryRouteManagers; @@ -17,6 +18,117 @@ namespace ShardingCore.Extensions */ public static class ShardingRouteExtension { + /// + /// 创建或者添加强制路由 + /// + /// + /// + /// + /// 任何一个tails被添加成功就返回成功 + public static bool TryCreateOrAddMustTail(this ShardingRouteContext shardingRouteContext, params string[] tails) where TEntity : class, IShardingTable + { + return TryCreateOrAddMustTail(shardingRouteContext, typeof(TEntity), tails); + } + /// + /// 创建或者添加强制路由 + /// + /// + /// + /// + /// 任何一个tails被添加成功就返回成功 + public static bool TryCreateOrAddMustTail(this ShardingRouteContext shardingRouteContext, Type entityType, params string[] tails) + { + if (shardingRouteContext == null) + { + return false; + } + + if (tails.IsEmpty()) + return false; + if (!entityType.IsShardingTable()) + throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}"); + if (!shardingRouteContext.Must.TryGetValue(entityType,out HashSet mustTails)) + { + mustTails = new HashSet(); + shardingRouteContext.Must.Add(entityType, mustTails); + } + + return tails.Select(o => mustTails.Add(o)).Any(o => o); + } + /// + /// 创建或者添加提示路由 + /// + /// + /// + /// + /// 任何一个tails被添加成功就返回成功 + public static bool TryCreateOrAddHintTail(this ShardingRouteContext shardingRouteContext, params string[] tails) where TEntity : class, IShardingTable + { + return TryCreateOrAddHintTail(shardingRouteContext, typeof(TEntity), tails); + } + /// + /// 创建或者添加提示路由 + /// + /// + /// + /// + /// 任何一个tails被添加成功就返回成功 + public static bool TryCreateOrAddHintTail(this ShardingRouteContext shardingRouteContext, Type entityType, params string[] tails) + { + if (shardingRouteContext == null) + { + return false; + } + + if (tails.IsEmpty()) + return false; + if (!entityType.IsShardingTable()) + throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}"); + if (!shardingRouteContext.Hint.TryGetValue(entityType, out HashSet hintTails)) + { + hintTails = new HashSet(); + shardingRouteContext.Hint.Add(entityType, hintTails); + } + + return tails.Select(o => hintTails.Add(o)).Any(o => o); + } + /// + /// 创建或者添加断言 + /// + /// + /// + /// + /// + public static bool TryCreateOrAddAssertTail(this ShardingRouteContext shardingRouteContext, params IRouteAssert[] tails) where TEntity : class, IShardingTable + { + return TryCreateOrAddAssertTail(shardingRouteContext, typeof(TEntity), tails); + } + public static bool TryCreateOrAddAssertTail(this ShardingRouteContext shardingRouteContext, Type entityType, params IRouteAssert[] asserts) + { + if (shardingRouteContext == null) + { + return false; + } + + if (asserts.IsEmpty()) + return false; + if (!entityType.IsShardingTable()) + throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}"); + if (!shardingRouteContext.Assert.TryGetValue(entityType, out LinkedList routeAsserts)) + { + routeAsserts = new LinkedList(); + shardingRouteContext.Assert.Add(entityType, routeAsserts); + } + foreach (var routeAssert in asserts) + { + routeAsserts.AddLast(routeAssert); + } + + return true; + } + + + public static bool TryGetMustTail(this ShardingRouteContext shardingRouteContext, out HashSet tail) where TEntity : class,IShardingTable { return TryGetMustTail(shardingRouteContext,typeof(TEntity),out tail); @@ -64,7 +176,7 @@ namespace ShardingCore.Extensions public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext, out ICollection tail)where TEntity : class,IShardingTable { - return shardingRouteContext.TryGetAssertTail(typeof(TEntity), out tail); + return TryGetAssertTail(shardingRouteContext,typeof(TEntity), out tail); } public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection tail) { diff --git a/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs index f9f2766a..1285c8d5 100644 --- a/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs @@ -25,6 +25,12 @@ namespace ShardingCore.VirtualRoutes.Mods protected readonly int Mod; protected readonly int TailLength; protected readonly char PaddingChar; + /// + /// + /// + /// 猴子长度 + /// 取模被除数 + /// 当取模后不足tailLength左补什么参数 protected AbstractSimpleShardingModKeyStringVirtualTableRoute(int tailLength,int mod,char paddingChar='0') { if(tailLength<1) @@ -47,15 +53,29 @@ namespace ShardingCore.VirtualRoutes.Mods var shardingKeyStr = ConvertToShardingKey(shardingKey); return Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % Mod).ToString().PadLeft(TailLength,PaddingChar);; } + /// + /// 将shardingKey转成对应的字符串 + /// + /// + /// protected override string ConvertToShardingKey(object shardingKey) { return shardingKey.ToString(); } + /// + /// 获取对应类型在数据库中的所有后缀 + /// + /// public override List GetAllTails() { return Enumerable.Range(0, Mod).Select(o => o.ToString().PadLeft(TailLength, PaddingChar)).ToList(); } - + /// + /// 路由表达式如何路由到正确的表 + /// + /// + /// + /// protected override Expression> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator) { var t = ShardingKeyToTail(shardingKey);