优化针对手动路由的操作

This commit is contained in:
xuejiaming 2021-08-26 08:54:47 +08:00
parent c8e020f51f
commit becb28595f
7 changed files with 159 additions and 5 deletions

View File

@ -68,7 +68,7 @@ namespace Sample.SqlServer.Controllers
using (_shardingRouteManager.CreateScope()) using (_shardingRouteManager.CreateScope())
{ {
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" }); _shardingRouteManager.Current.TryCreateOrAddMustTail<SysUserMod>("00");
var mod00s = await _defaultTableDbContext.Set<SysUserMod>().Skip(10).Take(11).ToListAsync(); var mod00s = await _defaultTableDbContext.Set<SysUserMod>().Skip(10).Take(11).ToListAsync();
} }

View File

@ -17,6 +17,7 @@ namespace Sample.SqlServer.Shardings
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod> public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{ {
protected override bool EnableHintRoute => true; protected override bool EnableHintRoute => true;
protected override bool EnableAssertRoute => true;
public SysUserModVirtualTableRoute() : base(2,3) public SysUserModVirtualTableRoute() : base(2,3)
{ {

View File

@ -18,6 +18,11 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
* @Ver: 1.0 * @Ver: 1.0
* @Email: 326308290@qq.com * @Email: 326308290@qq.com
*/ */
/// <summary>
/// 过滤虚拟路由用于处理强制路由、提示路由、路由断言
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class AbstractShardingFilterVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class, IShardingTable public abstract class AbstractShardingFilterVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class, IShardingTable
{ {
public ShardingRouteContext CurrentShardingRouteContext => public ShardingRouteContext CurrentShardingRouteContext =>

View File

@ -17,6 +17,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
*/ */
public abstract class AbstractShardingOperatorVirtualTableRoute<T, TKey> : AbstractShardingFilterVirtualTableRoute<T, TKey> where T : class, IShardingTable public abstract class AbstractShardingOperatorVirtualTableRoute<T, TKey> : AbstractShardingFilterVirtualTableRoute<T, TKey> where T : class, IShardingTable
{ {
protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable) protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
{ {
//获取所有需要路由的表后缀 //获取所有需要路由的表后缀

View File

@ -18,19 +18,34 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
public abstract class AbstractVirtualTableRoute<T, TKey> : IVirtualTableRoute<T> where T : class, IShardingTable public abstract class AbstractVirtualTableRoute<T, TKey> : IVirtualTableRoute<T> where T : class, IShardingTable
{ {
public Type ShardingEntityType => typeof(T); public Type ShardingEntityType => typeof(T);
/// <summary>
/// 如何将分表字段转成对应的类型
/// </summary>
/// <param name="shardingKey"></param>
/// <returns></returns>
protected abstract TKey ConvertToShardingKey(object shardingKey); protected abstract TKey ConvertToShardingKey(object shardingKey);
/// <summary>
/// 如何将分表字段转成后缀
/// </summary>
/// <param name="shardingKey"></param>
/// <returns></returns>
public abstract string ShardingKeyToTail(object shardingKey); public abstract string ShardingKeyToTail(object shardingKey);
/// <summary> /// <summary>
/// 对外路由方法 /// 根据表达式路由
/// </summary> /// </summary>
/// <param name="allPhysicTables"></param> /// <param name="allPhysicTables"></param>
/// <param name="queryable"></param> /// <param name="queryable"></param>
/// <returns></returns> /// <returns></returns>
public abstract List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable); public abstract List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
/// <summary>
/// 根据值路由
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="shardingKeyValue"></param>
/// <returns></returns>
public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKeyValue); public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKeyValue);
/// <summary> /// <summary>
/// 返回数据库现有的尾巴 /// 返回数据库现有的尾巴

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.Core; using ShardingCore.Core;
using ShardingCore.Core.QueryRouteManagers; using ShardingCore.Core.QueryRouteManagers;
@ -17,6 +18,117 @@ namespace ShardingCore.Extensions
*/ */
public static class ShardingRouteExtension public static class ShardingRouteExtension
{ {
/// <summary>
/// 创建或者添加强制路由
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="shardingRouteContext"></param>
/// <param name="tails"></param>
/// <returns>任何一个tails被添加成功就返回成功</returns>
public static bool TryCreateOrAddMustTail<TEntity>(this ShardingRouteContext shardingRouteContext, params string[] tails) where TEntity : class, IShardingTable
{
return TryCreateOrAddMustTail(shardingRouteContext, typeof(TEntity), tails);
}
/// <summary>
/// 创建或者添加强制路由
/// </summary>
/// <param name="shardingRouteContext"></param>
/// <param name="entityType"></param>
/// <param name="tails"></param>
/// <returns>任何一个tails被添加成功就返回成功</returns>
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<string> mustTails))
{
mustTails = new HashSet<string>();
shardingRouteContext.Must.Add(entityType, mustTails);
}
return tails.Select(o => mustTails.Add(o)).Any(o => o);
}
/// <summary>
/// 创建或者添加提示路由
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="shardingRouteContext"></param>
/// <param name="tails"></param>
/// <returns>任何一个tails被添加成功就返回成功</returns>
public static bool TryCreateOrAddHintTail<TEntity>(this ShardingRouteContext shardingRouteContext, params string[] tails) where TEntity : class, IShardingTable
{
return TryCreateOrAddHintTail(shardingRouteContext, typeof(TEntity), tails);
}
/// <summary>
/// 创建或者添加提示路由
/// </summary>
/// <param name="shardingRouteContext"></param>
/// <param name="entityType"></param>
/// <param name="tails"></param>
/// <returns>任何一个tails被添加成功就返回成功</returns>
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<string> hintTails))
{
hintTails = new HashSet<string>();
shardingRouteContext.Hint.Add(entityType, hintTails);
}
return tails.Select(o => hintTails.Add(o)).Any(o => o);
}
/// <summary>
/// 创建或者添加断言
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="shardingRouteContext"></param>
/// <param name="tails"></param>
/// <returns></returns>
public static bool TryCreateOrAddAssertTail<TEntity>(this ShardingRouteContext shardingRouteContext, params IRouteAssert<TEntity>[] 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<IRouteAssert> routeAsserts))
{
routeAsserts = new LinkedList<IRouteAssert>();
shardingRouteContext.Assert.Add(entityType, routeAsserts);
}
foreach (var routeAssert in asserts)
{
routeAsserts.AddLast(routeAssert);
}
return true;
}
public static bool TryGetMustTail<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> tail) where TEntity : class,IShardingTable public static bool TryGetMustTail<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> tail) where TEntity : class,IShardingTable
{ {
return TryGetMustTail(shardingRouteContext,typeof(TEntity),out tail); return TryGetMustTail(shardingRouteContext,typeof(TEntity),out tail);
@ -64,7 +176,7 @@ namespace ShardingCore.Extensions
public static bool TryGetAssertTail<TEntity>(this ShardingRouteContext shardingRouteContext, out ICollection<IRouteAssert> tail)where TEntity : class,IShardingTable public static bool TryGetAssertTail<TEntity>(this ShardingRouteContext shardingRouteContext, out ICollection<IRouteAssert> 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<IRouteAssert> tail) public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection<IRouteAssert> tail)
{ {

View File

@ -25,6 +25,12 @@ namespace ShardingCore.VirtualRoutes.Mods
protected readonly int Mod; protected readonly int Mod;
protected readonly int TailLength; protected readonly int TailLength;
protected readonly char PaddingChar; protected readonly char PaddingChar;
/// <summary>
///
/// </summary>
/// <param name="tailLength">猴子长度</param>
/// <param name="mod">取模被除数</param>
/// <param name="paddingChar">当取模后不足tailLength左补什么参数</param>
protected AbstractSimpleShardingModKeyStringVirtualTableRoute(int tailLength,int mod,char paddingChar='0') protected AbstractSimpleShardingModKeyStringVirtualTableRoute(int tailLength,int mod,char paddingChar='0')
{ {
if(tailLength<1) if(tailLength<1)
@ -47,15 +53,29 @@ namespace ShardingCore.VirtualRoutes.Mods
var shardingKeyStr = ConvertToShardingKey(shardingKey); var shardingKeyStr = ConvertToShardingKey(shardingKey);
return Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % Mod).ToString().PadLeft(TailLength,PaddingChar);; return Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % Mod).ToString().PadLeft(TailLength,PaddingChar);;
} }
/// <summary>
/// 将shardingKey转成对应的字符串
/// </summary>
/// <param name="shardingKey"></param>
/// <returns></returns>
protected override string ConvertToShardingKey(object shardingKey) protected override string ConvertToShardingKey(object shardingKey)
{ {
return shardingKey.ToString(); return shardingKey.ToString();
} }
/// <summary>
/// 获取对应类型在数据库中的所有后缀
/// </summary>
/// <returns></returns>
public override List<string> GetAllTails() public override List<string> GetAllTails()
{ {
return Enumerable.Range(0, Mod).Select(o => o.ToString().PadLeft(TailLength, PaddingChar)).ToList(); return Enumerable.Range(0, Mod).Select(o => o.ToString().PadLeft(TailLength, PaddingChar)).ToList();
} }
/// <summary>
/// 路由表达式如何路由到正确的表
/// </summary>
/// <param name="shardingKey"></param>
/// <param name="shardingOperator"></param>
/// <returns></returns>
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator) protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
{ {
var t = ShardingKeyToTail(shardingKey); var t = ShardingKeyToTail(shardingKey);