优化强制路由,添加断言路由,添加提示路由
This commit is contained in:
parent
27c97a0e51
commit
c8e020f51f
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.MySql.Domain.Maps;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace Sample.MySql.DbContexts
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.SqlServer3x.Domain.Maps;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace Sample.SqlServer3x
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
|
||||
namespace ShardingCore.Core.QueryRouteManagers.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 25 August 2021 20:46:51
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 路由断言
|
||||
/// </summary>
|
||||
public interface IRouteAssert
|
||||
{
|
||||
void Assert(List<IPhysicTable> allPhysicTables, List<IPhysicTable> resultPhysicTables);
|
||||
}
|
||||
|
||||
public interface IRouteAssert<T> : IRouteAssert where T : class, IShardingTable
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
|
@ -15,15 +16,23 @@ namespace ShardingCore.Core.QueryRouteManagers
|
|||
*/
|
||||
public class ShardingRouteContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 强制路由直接返回对应的后缀表
|
||||
/// </summary>
|
||||
public Dictionary<Type, HashSet<string>> Must { get; }
|
||||
public Dictionary<Type, HashSet<string>> Should { get; }
|
||||
public Dictionary<Type, HashSet<string>> ShouldNot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 提示路由会经过断言的强制路由
|
||||
/// </summary>
|
||||
public Dictionary<Type, HashSet<string>> Hint { get; }
|
||||
/// <summary>
|
||||
/// 断言
|
||||
/// </summary>
|
||||
public Dictionary<Type, LinkedList<IRouteAssert>> Assert { get; }
|
||||
private ShardingRouteContext()
|
||||
{
|
||||
Must = new Dictionary<Type, HashSet<string>>();
|
||||
Should = new Dictionary<Type, HashSet<string>>();
|
||||
ShouldNot = new Dictionary<Type, HashSet<string>>();
|
||||
Hint = new Dictionary<Type, HashSet<string>>();
|
||||
Assert = new Dictionary<Type, LinkedList<IRouteAssert>>();
|
||||
}
|
||||
|
||||
public static ShardingRouteContext Create()
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/25 17:23:42
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public abstract class AbstractShardingAssertVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class, IShardingTable
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/25 17:23:42
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public abstract class AbstractShardingFilterVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class, IShardingTable
|
||||
{
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
protected virtual bool EnableHintRoute => false;
|
||||
/// <summary>
|
||||
/// 启用断言路由
|
||||
/// </summary>
|
||||
protected virtual bool EnableAssertRoute => false;
|
||||
public override List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
|
||||
{
|
||||
//强制路由不经过断言
|
||||
if (EnableHintRoute)
|
||||
{
|
||||
if (CurrentShardingRouteContext != null)
|
||||
{
|
||||
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)
|
||||
throw new ShardingCoreException(
|
||||
$" sharding route must error:[{ShardingEntityType.FullName}]-->[{string.Join(",",mustTails)}]");
|
||||
return physicTables;
|
||||
}
|
||||
|
||||
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)
|
||||
throw new ShardingCoreException(
|
||||
$" sharding route hint error:[{ShardingEntityType.FullName}]-->[{string.Join(",",hintTails)}]");
|
||||
ProcessAssertRoutes(allPhysicTables, physicTables);
|
||||
return physicTables;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var filterPhysicTables = DoRouteWithPredicate(allPhysicTables,queryable);
|
||||
//后拦截器
|
||||
var resultPhysicTables = AfterPhysicTableFilter(allPhysicTables,filterPhysicTables);
|
||||
//最后处理断言
|
||||
ProcessAssertRoutes(allPhysicTables, resultPhysicTables);
|
||||
return resultPhysicTables;
|
||||
}
|
||||
|
||||
private void ProcessAssertRoutes(List<IPhysicTable> allPhysicTables,List<IPhysicTable> filterPhysicTables)
|
||||
{
|
||||
if (EnableAssertRoute)
|
||||
{
|
||||
if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertTail<T>(out ICollection<IRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty())
|
||||
{
|
||||
foreach (var routeAssert in routeAsserts)
|
||||
{
|
||||
routeAssert.Assert(allPhysicTables, filterPhysicTables);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 物理表过滤后
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables">所有的物理表</param>
|
||||
/// <param name="filterPhysicTables">过滤后的物理表</param>
|
||||
/// <returns></returns>
|
||||
protected virtual List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
||||
{
|
||||
return filterPhysicTables;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
* @Date: Saturday, 19 December 2020 19:55:24
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public abstract class AbstractShardingOperatorVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<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)
|
||||
{
|
||||
|
|
|
@ -19,62 +19,17 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
public Type ShardingEntityType => typeof(T);
|
||||
|
||||
public virtual ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
protected virtual bool EnableHintRoute => false;
|
||||
/// <summary>
|
||||
/// 跳过表达式路由
|
||||
/// </summary>
|
||||
protected virtual bool SkipRouteWithPredicate =>
|
||||
CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetMustTail<T>(out HashSet<string> mustTails) && mustTails.IsNotEmpty();
|
||||
|
||||
protected abstract TKey ConvertToShardingKey(object shardingKey);
|
||||
public abstract string ShardingKeyToTail(object shardingKey);
|
||||
|
||||
/// <summary>
|
||||
/// 对外路由方法
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
public virtual List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
|
||||
{
|
||||
if (EnableHintRoute&&SkipRouteWithPredicate)
|
||||
{
|
||||
var tails = CurrentShardingRouteContext.Must[ShardingEntityType];
|
||||
var physicTables = allPhysicTables.Where(o => tails.Contains(o.Tail)).ToList();
|
||||
if (physicTables.IsEmpty())
|
||||
throw new ShardingCoreException(
|
||||
$" sharding route must error:[{ShardingEntityType.FullName}]-->[{string.Join(",",tails)}]");
|
||||
return physicTables;
|
||||
}
|
||||
var filterPhysicTables = BeforePhysicTableFilter(allPhysicTables);
|
||||
filterPhysicTables = DoRouteWithPredicate(filterPhysicTables, queryable);
|
||||
return AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
|
||||
}
|
||||
protected virtual List<IPhysicTable> BeforePhysicTableFilter(List<IPhysicTable> allPhysicTables)
|
||||
{
|
||||
return allPhysicTables;
|
||||
}
|
||||
/// <summary>
|
||||
/// 实际路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
|
||||
/// <summary>
|
||||
/// 物理表过滤后
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables">所有的物理表</param>
|
||||
/// <param name="filterPhysicTables">过滤后的物理表</param>
|
||||
/// <returns></returns>
|
||||
protected virtual List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
||||
{
|
||||
return filterPhysicTables;
|
||||
}
|
||||
public abstract List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
|
||||
|
||||
|
||||
public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKeyValue);
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace ShardingCore.Exceptions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 25 August 2021 19:20:14
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingCoreAssertException:ShardingCoreException
|
||||
{
|
||||
|
||||
public ShardingCoreAssertException()
|
||||
{
|
||||
}
|
||||
|
||||
protected ShardingCoreAssertException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
public ShardingCoreAssertException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ShardingCoreAssertException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
|
||||
namespace ShardingCore.Extensions
|
||||
|
@ -38,5 +39,51 @@ namespace ShardingCore.Extensions
|
|||
tail = shardingRouteContext.Must[entityType];
|
||||
return true;
|
||||
}
|
||||
public static bool TryGetHintTail<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> tail) where TEntity : class,IShardingTable
|
||||
{
|
||||
return TryGetHintTail(shardingRouteContext,typeof(TEntity),out tail);
|
||||
}
|
||||
public static bool TryGetHintTail(this ShardingRouteContext shardingRouteContext,Type entityType, out HashSet<string> tail)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
if (!entityType.IsShardingTable())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
if (!shardingRouteContext.Hint.ContainsKey(entityType))
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
tail = shardingRouteContext.Hint[entityType];
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryGetAssertTail<TEntity>(this ShardingRouteContext shardingRouteContext, out ICollection<IRouteAssert> tail)where TEntity : class,IShardingTable
|
||||
{
|
||||
return shardingRouteContext.TryGetAssertTail(typeof(TEntity), out tail);
|
||||
}
|
||||
public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection<IRouteAssert> tail)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
if (!entityType.IsShardingTable())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
if (!shardingRouteContext.Assert.ContainsKey(entityType))
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
tail = shardingRouteContext.Assert[entityType];
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Test50.MySql.Domain.Maps;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Test50.MySql.Domain.Entities;
|
||||
|
||||
namespace ShardingCore.Test50.MySql.Shardings
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Test50_2x.Domain.Maps;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Test50_2x.Domain.Entities;
|
||||
|
||||
namespace ShardingCore.Test50_2x.Shardings
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Test50_3x.Domain.Maps;
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Test50_3x.Domain.Entities;
|
||||
|
||||
namespace ShardingCore.Test50_3x.Shardings
|
||||
|
|
Loading…
Reference in New Issue