完成分库版本支持分页配置
This commit is contained in:
parent
26f177aebb
commit
ce30a09fb6
|
@ -12,7 +12,7 @@ namespace Sample.SqlServer.Shardings
|
|||
public void Configure(PaginationBuilder<SysUserSalary> builder)
|
||||
{
|
||||
builder.PaginationSequence(o => o.Id)
|
||||
.UseTailComparer(Comparer<string>.Default)
|
||||
.UseRouteComparer(Comparer<string>.Default)
|
||||
.UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch);
|
||||
builder.PaginationSequence(o => o.DateOfMonth)
|
||||
.UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone(10);
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core.QueryRouteManagers.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/22 7:54:11
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 路由断言
|
||||
/// </summary>
|
||||
public interface IDataSourceRouteAssert
|
||||
{
|
||||
/// <summary>
|
||||
/// 断言路由结果
|
||||
/// </summary>
|
||||
/// <param name="allDataSources">所有的路由数据源</param>
|
||||
/// <param name="resultDataSources">本次查询路由返回结果</param>
|
||||
void Assert(List<string> allDataSources, List<string> resultDataSources);
|
||||
}
|
||||
|
||||
public interface IDataSourceRouteAssert<T> : IDataSourceRouteAssert where T : class, IShardingDataSource
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -13,12 +13,12 @@ namespace ShardingCore.Core.QueryRouteManagers.Abstractions
|
|||
/// <summary>
|
||||
/// 路由断言
|
||||
/// </summary>
|
||||
public interface IRouteAssert
|
||||
public interface ITableRouteAssert
|
||||
{
|
||||
void Assert(List<IPhysicTable> allPhysicTables, List<IPhysicTable> resultPhysicTables);
|
||||
}
|
||||
|
||||
public interface IRouteAssert<T> : IRouteAssert where T : class, IShardingTable
|
||||
public interface ITableRouteAssert<T> : ITableRouteAssert where T : class,IShardingTable
|
||||
{
|
||||
|
||||
}
|
|
@ -16,23 +16,43 @@ namespace ShardingCore.Core.QueryRouteManagers
|
|||
*/
|
||||
public class ShardingRouteContext
|
||||
{
|
||||
#region 分库提示路由
|
||||
/// <summary>
|
||||
/// 强制路由直接返回对应的后缀表
|
||||
/// </summary>
|
||||
public Dictionary<Type, HashSet<string>> Must { get; }
|
||||
public Dictionary<Type, HashSet<string>> MustDataSource { get; }
|
||||
/// <summary>
|
||||
/// 提示路由会经过断言的强制路由
|
||||
/// </summary>
|
||||
public Dictionary<Type, HashSet<string>> Hint { get; }
|
||||
public Dictionary<Type, HashSet<string>> HintDataSource { get; }
|
||||
/// <summary>
|
||||
/// 断言
|
||||
/// </summary>
|
||||
public Dictionary<Type, LinkedList<IRouteAssert>> Assert { get; }
|
||||
public Dictionary<Type, LinkedList<IDataSourceRouteAssert>> AssertDataSource { get; }
|
||||
#endregion
|
||||
|
||||
#region 分表提示路由
|
||||
/// <summary>
|
||||
/// 强制路由直接返回对应的后缀表
|
||||
/// </summary>
|
||||
public Dictionary<Type, HashSet<string>> MustTable { get; }
|
||||
/// <summary>
|
||||
/// 提示路由会经过断言的强制路由
|
||||
/// </summary>
|
||||
public Dictionary<Type, HashSet<string>> HintTable { get; }
|
||||
/// <summary>
|
||||
/// 断言
|
||||
/// </summary>
|
||||
public Dictionary<Type, LinkedList<ITableRouteAssert>> AssertTable { get; }
|
||||
#endregion
|
||||
private ShardingRouteContext()
|
||||
{
|
||||
Must = new Dictionary<Type, HashSet<string>>();
|
||||
Hint = new Dictionary<Type, HashSet<string>>();
|
||||
Assert = new Dictionary<Type, LinkedList<IRouteAssert>>();
|
||||
MustDataSource = new Dictionary<Type, HashSet<string>>();
|
||||
HintDataSource = new Dictionary<Type, HashSet<string>>();
|
||||
AssertDataSource = new Dictionary<Type, LinkedList<IDataSourceRouteAssert>>();
|
||||
MustTable = new Dictionary<Type, HashSet<string>>();
|
||||
HintTable = new Dictionary<Type, HashSet<string>>();
|
||||
AssertTable = new Dictionary<Type, LinkedList<ITableRouteAssert>>();
|
||||
}
|
||||
|
||||
public static ShardingRouteContext Create()
|
||||
|
|
|
@ -22,10 +22,11 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
string DefaultDataSourceName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <param name="routeRouteConfig"></param>
|
||||
/// <returns>data source names</returns>
|
||||
List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig);
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
var virtualDataSourceRoute = GetRoute( entityType);
|
||||
|
||||
if (routeRouteConfig.UseQueryable())
|
||||
return virtualDataSourceRoute.RouteWithWhere(routeRouteConfig.GetQueryable());
|
||||
return virtualDataSourceRoute.RouteWithPredicate(routeRouteConfig.GetQueryable(), true);
|
||||
if (routeRouteConfig.UsePredicate())
|
||||
return virtualDataSourceRoute.RouteWithWhere((IQueryable)Activator.CreateInstance(typeof(EnumerableQuery<>).MakeGenericType(entityType), routeRouteConfig.UsePredicate()));
|
||||
return virtualDataSourceRoute.RouteWithPredicate((IQueryable)Activator.CreateInstance(typeof(EnumerableQuery<>).MakeGenericType(entityType), routeRouteConfig.UsePredicate()), false);
|
||||
object shardingKeyValue = null;
|
||||
if (routeRouteConfig.UseValue())
|
||||
shardingKeyValue = routeRouteConfig.GetShardingKeyValue();
|
||||
|
@ -103,10 +103,10 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
public bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute)
|
||||
{
|
||||
if (!virtualDataSourceRoute.EntityType.IsShardingDataSource())
|
||||
throw new InvalidOperationException($"{virtualDataSourceRoute.EntityType.FullName} should impl {nameof(IShardingDataSource)}");
|
||||
if (!virtualDataSourceRoute.ShardingEntityType.IsShardingDataSource())
|
||||
throw new InvalidOperationException($"{virtualDataSourceRoute.ShardingEntityType.FullName} should impl {nameof(IShardingDataSource)}");
|
||||
|
||||
return _dataSourceVirtualRoutes.TryAdd(virtualDataSourceRoute.EntityType, virtualDataSourceRoute);
|
||||
return _dataSourceVirtualRoutes.TryAdd(virtualDataSourceRoute.ShardingEntityType, virtualDataSourceRoute);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,6 +40,7 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// 分库配置
|
||||
/// </summary>
|
||||
public PaginationMetadata PaginationMetadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用智能分页
|
||||
/// </summary>
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/25 17:23:42
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 过滤虚拟路由用于处理强制路由、提示路由、路由断言
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
public abstract class AbstractShardingFilterVirtualDataSourceRoute<T, TKey> : AbstractVirtualDataSourceRoute<T, TKey> where T : class, IShardingDataSource
|
||||
{
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
protected virtual bool EnableHintRoute => false;
|
||||
/// <summary>
|
||||
/// 启用断言路由
|
||||
/// </summary>
|
||||
protected virtual bool EnableAssertRoute => false;
|
||||
public override List<string> RouteWithPredicate(IQueryable queryable,bool isQuery)
|
||||
{
|
||||
var allDataSourceNames = GetAllDataSourceNames();
|
||||
if (!isQuery)
|
||||
{
|
||||
//后拦截器
|
||||
return AfterDataSourceFilter(allDataSourceNames, DoRouteWithPredicate(allDataSourceNames, queryable));
|
||||
}
|
||||
//强制路由不经过断言
|
||||
if (EnableHintRoute)
|
||||
{
|
||||
if (CurrentShardingRouteContext != null)
|
||||
{
|
||||
if (CurrentShardingRouteContext.TryGetMustDataSource<T>(out HashSet<string> mustDataSources) && mustDataSources.IsNotEmpty())
|
||||
{
|
||||
var dataSources = allDataSourceNames.Where(o => mustDataSources.Contains(o)).ToList();
|
||||
if (dataSources.IsEmpty()||dataSources.Count!=mustDataSources.Count)
|
||||
throw new ShardingCoreException(
|
||||
$" sharding data source route must error:[{ShardingEntityType.FullName}]-->[{string.Join(",",mustDataSources)}]");
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
if (CurrentShardingRouteContext.TryGetHintDataSource<T>(out HashSet<string> hintDataSouces) && hintDataSouces.IsNotEmpty())
|
||||
{
|
||||
var dataSources = allDataSourceNames.Where(o => hintDataSouces.Contains(o)).ToList();
|
||||
if (dataSources.IsEmpty()||dataSources.Count!=hintDataSouces.Count)
|
||||
throw new ShardingCoreException(
|
||||
$" sharding data source route hint error:[{ShardingEntityType.FullName}]-->[{string.Join(",",hintDataSouces)}]");
|
||||
ProcessAssertRoutes(allDataSourceNames, dataSources);
|
||||
return dataSources;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var filterDataSources = DoRouteWithPredicate(allDataSourceNames, queryable);
|
||||
//后拦截器
|
||||
var resultDataSources = AfterDataSourceFilter(allDataSourceNames, filterDataSources);
|
||||
//最后处理断言
|
||||
ProcessAssertRoutes(allDataSourceNames, resultDataSources);
|
||||
return resultDataSources;
|
||||
}
|
||||
|
||||
private void ProcessAssertRoutes(List<string> allDataSources,List<string> filterDataSources)
|
||||
{
|
||||
if (EnableAssertRoute)
|
||||
{
|
||||
if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertDataSource<T>(out ICollection<IDataSourceRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty())
|
||||
{
|
||||
foreach (var routeAssert in routeAsserts)
|
||||
{
|
||||
routeAssert.Assert(allDataSources, filterDataSources);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<string> DoRouteWithPredicate(List<string> allDataSourceNames, IQueryable queryable);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 物理表过滤后
|
||||
/// </summary>
|
||||
/// <param name="allDataSourceNames">所有的物理表</param>
|
||||
/// <param name="filterDataSources">过滤后的物理表</param>
|
||||
/// <returns></returns>
|
||||
protected virtual List<string> AfterDataSourceFilter(List<string> allDataSourceNames, List<string> filterDataSources)
|
||||
{
|
||||
return filterDataSources;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Utils;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 19 December 2020 19:55:24
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 抽象类型抽象出对应的条件表达式
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
public abstract class AbstractShardingOperatorVirtualDataSourceRoute<T, TKey> : AbstractShardingFilterVirtualDataSourceRoute<T, TKey> where T : class, IShardingDataSource
|
||||
{
|
||||
|
||||
protected override List<string> DoRouteWithPredicate(List<string> allDataSourceNames, IQueryable queryable)
|
||||
{
|
||||
//获取所有需要路由的表后缀
|
||||
var filter = ShardingUtil.GetRouteShardingTableFilter(queryable, ShardingUtil.Parse(typeof(T)), ConvertToShardingKey, GetRouteToFilter);
|
||||
var dataSources = allDataSourceNames.Where(o => filter(o)).ToList();
|
||||
return dataSources;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 如何路由到具体表 shardingKeyValue:分表的值, 返回结果:如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表
|
||||
/// </summary>
|
||||
/// <param name="shardingKey">分表的值</param>
|
||||
/// <param name="shardingOperator">操作</param>
|
||||
/// <returns>如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表</returns>
|
||||
protected abstract Expression<Func<string, bool>> GetRouteToFilter(TKey shardingKey, ShardingOperatorEnum shardingOperator);
|
||||
|
||||
public override string RouteWithValue(object shardingKey)
|
||||
{
|
||||
var allDataSourceNames = GetAllDataSourceNames();
|
||||
var shardingKeyToDataSource = ShardingKeyToDataSourceName(shardingKey);
|
||||
|
||||
var dataSources = allDataSourceNames.Where(o => o== shardingKeyToDataSource).ToList();
|
||||
if (dataSources.IsEmpty())
|
||||
{
|
||||
var routeConfig = ShardingUtil.Parse(typeof(T));
|
||||
throw new ShardingKeyRouteNotMatchException($"{routeConfig.EntityType} -> [{routeConfig.ShardingTableField}] ->【{shardingKey}】 all data sources ->[{string.Join(",", allDataSourceNames.Select(o=>o))}]");
|
||||
}
|
||||
|
||||
if (dataSources.Count > 1)
|
||||
throw new ShardingKeyRouteMoreException($"data source:{string.Join(",", dataSources.Select(o => $"[{o}]"))}");
|
||||
return dataSources[0];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 18 December 2020 14:33:01
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public abstract class AbstractVirtualDataSourceRoute<T, TKey> : IVirtualDataSourceRoute<T> where T : class, IShardingDataSource
|
||||
{
|
||||
public void Init()
|
||||
{
|
||||
var paginationConfiguration = CreatePaginationConfiguration();
|
||||
if (paginationConfiguration != null)
|
||||
{
|
||||
PaginationMetadata = new PaginationMetadata();
|
||||
var paginationBuilder = new PaginationBuilder<T>(PaginationMetadata);
|
||||
paginationConfiguration.Configure(paginationBuilder);
|
||||
}
|
||||
}
|
||||
public virtual IPaginationConfiguration<T> CreatePaginationConfiguration()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// entity type
|
||||
/// </summary>
|
||||
public Type ShardingEntityType => typeof(T);
|
||||
|
||||
public new PaginationMetadata PaginationMetadata { get; protected set; }
|
||||
public bool EnablePagination => PaginationMetadata != null;
|
||||
|
||||
/// <summary>
|
||||
/// 分库字段object类型的如何转成对应的泛型类型how convert sharding key to generic type key value
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract TKey ConvertToShardingKey(object shardingKey);
|
||||
/// <summary>
|
||||
/// 分库字段如何转成对应的数据源名称 how convert sharding data source key to data source name
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
public abstract string ShardingKeyToDataSourceName(object shardingKey);
|
||||
|
||||
/// <summary>
|
||||
/// 根据表达式返回对应的数据源名称 find data source names with queryable
|
||||
/// </summary>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="isQuery"></param>
|
||||
/// <returns></returns>
|
||||
public abstract List<string> RouteWithPredicate(IQueryable queryable, bool isQuery);
|
||||
/// <summary>
|
||||
/// 值如何转成对应的数据源
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
public abstract string RouteWithValue(object shardingKey);
|
||||
|
||||
public abstract List<string> GetAllDataSourceNames();
|
||||
public abstract bool AddDataSourceName(string dataSourceName);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes
|
||||
{
|
||||
|
@ -13,15 +14,24 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes
|
|||
*/
|
||||
public interface IVirtualDataSourceRoute
|
||||
{
|
||||
Type EntityType { get; }
|
||||
Type ShardingEntityType { get;}
|
||||
/// <summary>
|
||||
/// 分页配置
|
||||
/// </summary>
|
||||
PaginationMetadata PaginationMetadata { get; }
|
||||
/// <summary>
|
||||
/// 是否启用分页配置
|
||||
/// </summary>
|
||||
bool EnablePagination { get; }
|
||||
string ShardingKeyToDataSourceName(object shardingKeyValue);
|
||||
|
||||
/// <summary>
|
||||
/// 根据查询条件路由返回物理数据源
|
||||
/// </summary>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="isQuery"></param>
|
||||
/// <returns>data source name</returns>
|
||||
List<string> RouteWithWhere(IQueryable queryable);
|
||||
List<string> RouteWithPredicate(IQueryable queryable, bool isQuery);
|
||||
|
||||
/// <summary>
|
||||
/// 根据值进行路由
|
||||
|
@ -31,10 +41,25 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes
|
|||
string RouteWithValue(object shardingKeyValue);
|
||||
|
||||
List<string> GetAllDataSourceNames();
|
||||
/// <summary>
|
||||
/// 添加数据源
|
||||
/// </summary>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <returns></returns>
|
||||
bool AddDataSourceName(string dataSourceName);
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
void Init();
|
||||
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceRoute<T> : IVirtualDataSourceRoute where T : class
|
||||
public interface IVirtualDataSourceRoute<T> : IVirtualDataSourceRoute where T : class, IShardingDataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回null就是表示不开启分页配置
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IPaginationConfiguration<T> CreatePaginationConfiguration();
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
if (EnableAssertRoute)
|
||||
{
|
||||
if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertTail<T>(out ICollection<IRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty())
|
||||
if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertTail<T>(out ICollection<ITableRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty())
|
||||
{
|
||||
foreach (var routeAssert in routeAsserts)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
|
||||
public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
||||
{
|
||||
var shardingKeyToTail = ShardingKeyToTail(ConvertToShardingKey(shardingKey));
|
||||
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||
|
||||
var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
|
||||
if (physicTables.IsEmpty())
|
||||
|
|
|
@ -51,9 +51,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
/// 根据值路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="shardingKeyValue"></param>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKeyValue);
|
||||
public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey);
|
||||
/// <summary>
|
||||
/// 返回数据库现有的尾巴
|
||||
/// </summary>
|
||||
|
|
|
@ -33,9 +33,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
|
|||
/// 根据值进行路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="shardingKeyValue"></param>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKeyValue);
|
||||
IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey);
|
||||
/// <summary>
|
||||
/// 获取所有的目前数据库存在的尾巴
|
||||
/// get all tails in the db
|
||||
|
|
|
@ -25,5 +25,15 @@ namespace ShardingCore.Extensions.InternalExtensions
|
|||
{
|
||||
return condition ? source.OrderByDescending(keySelector, comparer) : source;
|
||||
}
|
||||
public static IOrderedEnumerable<TShource> ThenByIf<TShource, TKey>(this IOrderedEnumerable<TShource> source, Func<TShource, TKey> keySelector, bool condition,
|
||||
IComparer<TKey>? comparer)
|
||||
{
|
||||
return condition ? source.ThenBy(keySelector, comparer) : source;
|
||||
}
|
||||
public static IOrderedEnumerable<TShource> ThenByDescendingIf<TShource, TKey>(this IOrderedEnumerable<TShource> source, Func<TShource, TKey> keySelector, bool condition,
|
||||
IComparer<TKey>? comparer)
|
||||
{
|
||||
return condition ? source.ThenByDescending(keySelector, comparer) : source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
|
||||
namespace ShardingCore.Extensions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/23 22:19:24
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public static class ShardingDataSourceRouteExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建或者添加强制路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="shardingRouteContext"></param>
|
||||
/// <param name="dataSources"></param>
|
||||
/// <returns>任何一个dataSources被添加成功就返回成功</returns>
|
||||
public static bool TryCreateOrAddMustDataSource<TEntity>(this ShardingRouteContext shardingRouteContext, params string[] dataSources) where TEntity : class, IShardingDataSource
|
||||
{
|
||||
return TryCreateOrAddMustDataSource(shardingRouteContext, typeof(TEntity), dataSources);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建或者添加强制路由
|
||||
/// </summary>
|
||||
/// <param name="shardingRouteContext"></param>
|
||||
/// <param name="entityType"></param>
|
||||
/// <param name="dataSources"></param>
|
||||
/// <returns>任何一个dataSources被添加成功就返回成功</returns>
|
||||
public static bool TryCreateOrAddMustDataSource(this ShardingRouteContext shardingRouteContext, Type entityType, params string[] dataSources)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dataSources.IsEmpty())
|
||||
return false;
|
||||
if (!entityType.IsShardingDataSource())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingDataSource)}");
|
||||
if (!shardingRouteContext.MustDataSource.TryGetValue(entityType,out HashSet<string> mustDataSources))
|
||||
{
|
||||
mustDataSources = new HashSet<string>();
|
||||
shardingRouteContext.MustDataSource.Add(entityType, mustDataSources);
|
||||
}
|
||||
|
||||
return dataSources.Select(o => mustDataSources.Add(o)).Any(o => o);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建或者添加提示路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="shardingRouteContext"></param>
|
||||
/// <param name="dataSources"></param>
|
||||
/// <returns>任何一个dataSources被添加成功就返回成功</returns>
|
||||
public static bool TryCreateOrAddHintDataSource<TEntity>(this ShardingRouteContext shardingRouteContext, params string[] dataSources) where TEntity : class, IShardingDataSource
|
||||
{
|
||||
return TryCreateOrAddHintDataSource(shardingRouteContext, typeof(TEntity), dataSources);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建或者添加提示路由
|
||||
/// </summary>
|
||||
/// <param name="shardingRouteContext"></param>
|
||||
/// <param name="entityType"></param>
|
||||
/// <param name="dataSources"></param>
|
||||
/// <returns>任何一个dataSources被添加成功就返回成功</returns>
|
||||
public static bool TryCreateOrAddHintDataSource(this ShardingRouteContext shardingRouteContext, Type entityType, params string[] dataSources)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dataSources.IsEmpty())
|
||||
return false;
|
||||
if (!entityType.IsShardingDataSource())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingDataSource)}");
|
||||
if (!shardingRouteContext.HintDataSource.TryGetValue(entityType, out HashSet<string> hintDataSources))
|
||||
{
|
||||
hintDataSources = new HashSet<string>();
|
||||
shardingRouteContext.HintDataSource.Add(entityType, hintDataSources);
|
||||
}
|
||||
|
||||
return dataSources.Select(o => hintDataSources.Add(o)).Any(o => o);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建或者添加断言
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="shardingRouteContext"></param>
|
||||
/// <param name="dataSources"></param>
|
||||
/// <returns></returns>
|
||||
public static bool TryCreateOrAddAssertDataSource<TEntity>(this ShardingRouteContext shardingRouteContext, params IDataSourceRouteAssert<TEntity>[] dataSources) where TEntity : class, IShardingDataSource
|
||||
{
|
||||
return TryCreateOrAddAssertDataSource(shardingRouteContext, typeof(TEntity), dataSources);
|
||||
}
|
||||
public static bool TryCreateOrAddAssertDataSource(this ShardingRouteContext shardingRouteContext, Type entityType, params IDataSourceRouteAssert[] asserts)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (asserts.IsEmpty())
|
||||
return false;
|
||||
if (!entityType.IsShardingDataSource())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingDataSource)}");
|
||||
if (!shardingRouteContext.AssertDataSource.TryGetValue(entityType, out LinkedList<IDataSourceRouteAssert> routeAsserts))
|
||||
{
|
||||
routeAsserts = new LinkedList<IDataSourceRouteAssert>();
|
||||
shardingRouteContext.AssertDataSource.Add(entityType, routeAsserts);
|
||||
}
|
||||
foreach (var routeAssert in asserts)
|
||||
{
|
||||
routeAsserts.AddLast(routeAssert);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool TryGetMustDataSource<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> dataSources) where TEntity : class, IShardingDataSource
|
||||
{
|
||||
return TryGetMustDataSource(shardingRouteContext,typeof(TEntity),out dataSources);
|
||||
}
|
||||
public static bool TryGetMustDataSource(this ShardingRouteContext shardingRouteContext,Type entityType, out HashSet<string> dataSources)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
dataSources = null;
|
||||
return false;
|
||||
}
|
||||
if (!entityType.IsShardingDataSource())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingDataSource)}");
|
||||
if (!shardingRouteContext.MustDataSource.ContainsKey(entityType))
|
||||
{
|
||||
dataSources = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
dataSources = shardingRouteContext.MustDataSource[entityType];
|
||||
return true;
|
||||
}
|
||||
public static bool TryGetHintDataSource<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> dataSources) where TEntity : class,IShardingDataSource
|
||||
{
|
||||
return TryGetHintDataSource(shardingRouteContext,typeof(TEntity),out dataSources);
|
||||
}
|
||||
public static bool TryGetHintDataSource(this ShardingRouteContext shardingRouteContext,Type entityType, out HashSet<string> dataSources)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
dataSources = null;
|
||||
return false;
|
||||
}
|
||||
if (!entityType.IsShardingDataSource())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingDataSource)}");
|
||||
if (!shardingRouteContext.HintDataSource.ContainsKey(entityType))
|
||||
{
|
||||
dataSources = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
dataSources = shardingRouteContext.HintDataSource[entityType];
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryGetAssertDataSource<TEntity>(this ShardingRouteContext shardingRouteContext, out ICollection<IDataSourceRouteAssert> dataSources)where TEntity : class,IShardingDataSource
|
||||
{
|
||||
return TryGetAssertDataSource(shardingRouteContext,typeof(TEntity), out dataSources);
|
||||
}
|
||||
public static bool TryGetAssertDataSource(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection<IDataSourceRouteAssert> dataSources)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
dataSources = null;
|
||||
return false;
|
||||
}
|
||||
if (!entityType.IsShardingDataSource())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingDataSource)}");
|
||||
if (!shardingRouteContext.AssertDataSource.ContainsKey(entityType))
|
||||
{
|
||||
dataSources = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
dataSources = shardingRouteContext.AssertDataSource[entityType];
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ namespace ShardingCore.Extensions
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public static class ShardingRouteExtension
|
||||
public static class ShardingTableRouteExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建或者添加强制路由
|
||||
|
@ -47,10 +47,10 @@ namespace ShardingCore.Extensions
|
|||
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))
|
||||
if (!shardingRouteContext.MustTable.TryGetValue(entityType,out HashSet<string> mustTails))
|
||||
{
|
||||
mustTails = new HashSet<string>();
|
||||
shardingRouteContext.Must.Add(entityType, mustTails);
|
||||
shardingRouteContext.MustTable.Add(entityType, mustTails);
|
||||
}
|
||||
|
||||
return tails.Select(o => mustTails.Add(o)).Any(o => o);
|
||||
|
@ -84,10 +84,10 @@ namespace ShardingCore.Extensions
|
|||
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))
|
||||
if (!shardingRouteContext.HintTable.TryGetValue(entityType, out HashSet<string> hintTails))
|
||||
{
|
||||
hintTails = new HashSet<string>();
|
||||
shardingRouteContext.Hint.Add(entityType, hintTails);
|
||||
shardingRouteContext.HintTable.Add(entityType, hintTails);
|
||||
}
|
||||
|
||||
return tails.Select(o => hintTails.Add(o)).Any(o => o);
|
||||
|
@ -99,11 +99,11 @@ namespace ShardingCore.Extensions
|
|||
/// <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
|
||||
public static bool TryCreateOrAddAssertTail<TEntity>(this ShardingRouteContext shardingRouteContext, params ITableRouteAssert<TEntity>[] tails) where TEntity : class, IShardingTable
|
||||
{
|
||||
return TryCreateOrAddAssertTail(shardingRouteContext, typeof(TEntity), tails);
|
||||
}
|
||||
public static bool TryCreateOrAddAssertTail(this ShardingRouteContext shardingRouteContext, Type entityType, params IRouteAssert[] asserts)
|
||||
public static bool TryCreateOrAddAssertTail(this ShardingRouteContext shardingRouteContext, Type entityType, params ITableRouteAssert[] asserts)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
|
@ -114,10 +114,10 @@ namespace ShardingCore.Extensions
|
|||
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))
|
||||
if (!shardingRouteContext.AssertTable.TryGetValue(entityType, out LinkedList<ITableRouteAssert> routeAsserts))
|
||||
{
|
||||
routeAsserts = new LinkedList<IRouteAssert>();
|
||||
shardingRouteContext.Assert.Add(entityType, routeAsserts);
|
||||
routeAsserts = new LinkedList<ITableRouteAssert>();
|
||||
shardingRouteContext.AssertTable.Add(entityType, routeAsserts);
|
||||
}
|
||||
foreach (var routeAssert in asserts)
|
||||
{
|
||||
|
@ -142,13 +142,13 @@ namespace ShardingCore.Extensions
|
|||
}
|
||||
if (!entityType.IsShardingTable())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
if (!shardingRouteContext.Must.ContainsKey(entityType))
|
||||
if (!shardingRouteContext.MustTable.ContainsKey(entityType))
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
tail = shardingRouteContext.Must[entityType];
|
||||
tail = shardingRouteContext.MustTable[entityType];
|
||||
return true;
|
||||
}
|
||||
public static bool TryGetHintTail<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> tail) where TEntity : class,IShardingTable
|
||||
|
@ -164,21 +164,21 @@ namespace ShardingCore.Extensions
|
|||
}
|
||||
if (!entityType.IsShardingTable())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
if (!shardingRouteContext.Hint.ContainsKey(entityType))
|
||||
if (!shardingRouteContext.HintTable.ContainsKey(entityType))
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
tail = shardingRouteContext.Hint[entityType];
|
||||
tail = shardingRouteContext.HintTable[entityType];
|
||||
return true;
|
||||
}
|
||||
|
||||
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<ITableRouteAssert> tail)where TEntity : class,IShardingTable
|
||||
{
|
||||
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<ITableRouteAssert> tail)
|
||||
{
|
||||
if (shardingRouteContext == null)
|
||||
{
|
||||
|
@ -187,13 +187,13 @@ namespace ShardingCore.Extensions
|
|||
}
|
||||
if (!entityType.IsShardingTable())
|
||||
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
if (!shardingRouteContext.Assert.ContainsKey(entityType))
|
||||
if (!shardingRouteContext.AssertTable.ContainsKey(entityType))
|
||||
{
|
||||
tail = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
tail = shardingRouteContext.Assert[entityType];
|
||||
tail = shardingRouteContext.AssertTable[entityType];
|
||||
return true;
|
||||
}
|
||||
|
|
@ -19,19 +19,45 @@ namespace ShardingCore.Extensions
|
|||
/// <param name="streamMergeContext"></param>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
public static bool IsNormalQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
return streamMergeContext.TableRouteResults.Count() > 1;
|
||||
return streamMergeContext.QueryEntities.Any(o=>!o.IsShardingDataSource()&&!o.IsShardingTable());
|
||||
}
|
||||
/// <summary>
|
||||
/// 单路由查询
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="streamMergeContext"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsSingleRouteQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
return streamMergeContext.DataSourceRouteResult.IntersectDataSources.Count==1&&streamMergeContext.TableRouteResults.Count()==1;
|
||||
}
|
||||
/// <summary>
|
||||
/// 单表查询
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="streamMergeContext"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsSingleShardingTableQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
return streamMergeContext.TableRouteResults.First().ReplaceTables.Count(o => o.EntityType.IsShardingTable()) == 1;
|
||||
}
|
||||
|
||||
public static IVirtualTableManager GetVirtualTableManager<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
/// <summary>
|
||||
/// 本次查询仅包含一个对象的分表分库
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <param name="streamMergeContext"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsSingleShardingQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
return (IVirtualTableManager)ShardingContainer.GetService(
|
||||
typeof(IVirtualTableManager<>).GetGenericType0(streamMergeContext.GetShardingDbContext().GetType()));
|
||||
return streamMergeContext.GetOriginalQueryable().ParseQueryableRoute().Count(o=>o.IsShardingTable()||o.IsShardingDataSource())==1;
|
||||
}
|
||||
public static bool IsSupportPaginationQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
var queryEntities = streamMergeContext.GetOriginalQueryable().ParseQueryableRoute();
|
||||
//仅一个对象支持分库或者分表的组合
|
||||
return queryEntities.Count(o=>(o.IsShardingDataSource()&&!o.IsShardingTable()) ||(o.IsShardingDataSource()&& o.IsShardingTable())|| (!o.IsShardingDataSource() && o.IsShardingTable())) ==1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IPaginationConfiguration<TEntity> where TEntity : class,IShardingTable
|
||||
public interface IPaginationConfiguration<TEntity> where TEntity : class
|
||||
{
|
||||
void Configure(PaginationBuilder<TEntity> builder);
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
/// <summary>
|
||||
/// 使用哪个后缀比较
|
||||
/// </summary>
|
||||
/// <param name="tailComparer"></param>
|
||||
/// <param name="routeComparer"></param>
|
||||
/// <returns></returns>
|
||||
public PaginationOrderPropertyBuilder UseTailComparer(IComparer<string> tailComparer)
|
||||
public PaginationOrderPropertyBuilder UseRouteComparer(IComparer<string> routeComparer)
|
||||
{
|
||||
|
||||
_paginationSequenceConfig.TailComparer= tailComparer ?? throw new ArgumentException(nameof(tailComparer));
|
||||
_paginationSequenceConfig.RouteComparer= routeComparer ?? throw new ArgumentException(nameof(routeComparer));
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -45,10 +45,12 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
/// 如果查询没发现排序就将当前配置追加上去
|
||||
/// </summary>
|
||||
/// <param name="order">大于等于0生效,越大优先级越高</param>
|
||||
/// <param name="defAsc">默认asc还是desc</param>
|
||||
/// <returns></returns>
|
||||
public PaginationOrderPropertyBuilder UseAppendIfOrderNone(int order=0)
|
||||
public PaginationOrderPropertyBuilder UseAppendIfOrderNone(int order=0,bool defAsc=true)
|
||||
{
|
||||
_paginationSequenceConfig.AppendOrder = order;
|
||||
_paginationSequenceConfig.AppendAsc = defAsc;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,16 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
*/
|
||||
public class PaginationSequenceConfig
|
||||
{
|
||||
public PaginationSequenceConfig(LambdaExpression orderPropertyExpression, PaginationMatchEnum paginationMatchEnum= PaginationMatchEnum.Owner, IComparer<string> tailComparer=null)
|
||||
public PaginationSequenceConfig(LambdaExpression orderPropertyExpression, PaginationMatchEnum paginationMatchEnum= PaginationMatchEnum.Owner, IComparer<string> routeComparer=null)
|
||||
{
|
||||
OrderPropertyInfo = orderPropertyExpression.GetPropertyAccess();
|
||||
PropertyName = OrderPropertyInfo.Name;
|
||||
PaginationMatchEnum = paginationMatchEnum;
|
||||
TailComparer = tailComparer ?? Comparer<string>.Default;
|
||||
RouteComparer = routeComparer ?? Comparer<string>.Default;
|
||||
SequenceTails = new HashSet<string>();
|
||||
}
|
||||
|
||||
public IComparer<string> TailComparer { get; set; }
|
||||
public IComparer<string> RouteComparer { get; set; }
|
||||
public PaginationMatchEnum PaginationMatchEnum { get; set; }
|
||||
public PropertyInfo OrderPropertyInfo { get; set; }
|
||||
|
||||
|
@ -38,6 +38,8 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
/// 大于等于0表示需要
|
||||
/// </summary>
|
||||
public int AppendOrder { get; set; } = -1;
|
||||
|
||||
public bool AppendAsc { get; set; } = true;
|
||||
public string PropertyName { get;}
|
||||
|
||||
public ISet<string> SequenceTails { get; }
|
||||
|
|
|
@ -138,8 +138,8 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
|
|||
var streamMergeContext = streamMergeContextMethod.MakeGenericMethod(new Type[] { queryEntityType }).Invoke(streamMergeContextFactory, new[] { queryable, shardingDbContext });
|
||||
|
||||
|
||||
Type streamMergeEngineType = typeof(AsyncEnumerableStreamMergeEngine<>);
|
||||
streamMergeEngineType = streamMergeEngineType.MakeGenericType(queryEntityType);
|
||||
Type streamMergeEngineType = typeof(AsyncEnumerableStreamMergeEngine<,>);
|
||||
streamMergeEngineType = streamMergeEngineType.MakeGenericType(shardingDbContext.GetType(), queryEntityType);
|
||||
return (TResult)Activator.CreateInstance(streamMergeEngineType, streamMergeContext);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,10 +4,15 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core.Internal.Visitors;
|
||||
using ShardingCore.Core.ShardingPage.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
@ -25,75 +30,52 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class EnumeratorShardingQueryExecutor<TEntity>
|
||||
public class EnumeratorShardingQueryExecutor<TShardingDbContext, TEntity>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly StreamMergeContext<TEntity> _streamMergeContext;
|
||||
private readonly IShardingPageManager _shardingPageManager;
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
|
||||
public EnumeratorShardingQueryExecutor(StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
_streamMergeContext = streamMergeContext;
|
||||
_shardingPageManager = ShardingContainer.GetService<IShardingPageManager>();
|
||||
_virtualTableManager = streamMergeContext.GetVirtualTableManager();
|
||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
|
||||
_virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
|
||||
}
|
||||
|
||||
public IEnumeratorStreamMergeEngine<TEntity> ExecuteAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
//操作单表
|
||||
if (!_streamMergeContext.IsShardingQuery())
|
||||
//操作单表或者单分库分表之类的
|
||||
if (_streamMergeContext.IsNormalQuery()||_streamMergeContext.IsSingleRouteQuery())
|
||||
{
|
||||
return new SingleQueryEnumeratorAsyncStreamMergeEngine<TEntity>(_streamMergeContext);
|
||||
return new SingleQueryEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity>(_streamMergeContext);
|
||||
}
|
||||
|
||||
//未开启系统分表或者本次查询涉及多张分表
|
||||
if (_streamMergeContext.IsPaginationQuery() && _streamMergeContext.IsSingleShardingTableQuery() && _shardingPageManager.Current != null)
|
||||
if (_streamMergeContext.IsPaginationQuery() && _streamMergeContext.IsSupportPaginationQuery() && _shardingPageManager.Current != null)
|
||||
{
|
||||
//获取虚拟表判断是否启用了分页配置
|
||||
var shardingEntityType = _streamMergeContext.TableRouteResults.First().ReplaceTables.First().EntityType;
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntityType);
|
||||
if (virtualTable.EnablePagination)
|
||||
{
|
||||
var paginationMetadata = virtualTable.PaginationMetadata;
|
||||
//判断本次查询的排序是否包含order,如果不包含就获取默认添加的排序
|
||||
var shardingEntityType = _streamMergeContext.QueryEntities.FirstOrDefault(o => o.IsShardingDataSource() || o.IsShardingTable());
|
||||
if (shardingEntityType == null)
|
||||
throw new ShardingCoreException($"query not found sharding data source or sharding table entity");
|
||||
|
||||
if (_streamMergeContext.Orders.IsEmpty())
|
||||
{
|
||||
//自动添加属性顺序排序
|
||||
//除了判断属性名还要判断所属关系
|
||||
var appendPaginationConfig = paginationMetadata.PaginationConfigs.OrderByDescending(o => o.AppendOrder)
|
||||
.FirstOrDefault(o => o.AppendIfOrderNone && typeof(TEntity).ContainPropertyName(o.PropertyName) && PaginationMatch(o));
|
||||
if (appendPaginationConfig != null)
|
||||
{
|
||||
return new AppenOrderSequenceEnumeratorAsyncStreamMergeEngine<TEntity>(_streamMergeContext, appendPaginationConfig, _shardingPageManager.Current.RouteQueryResults);
|
||||
}
|
||||
var mergeEngine = DoNoOrderAppendEnumeratorStreamMergeEngine(shardingEntityType);
|
||||
if (mergeEngine != null)
|
||||
return mergeEngine;
|
||||
}
|
||||
else
|
||||
{
|
||||
var orderCount = _streamMergeContext.Orders.Count();
|
||||
var primaryOrder = _streamMergeContext.Orders.First();
|
||||
if (orderCount == 1)
|
||||
{
|
||||
var sequenceFullMatchOrderConfig = paginationMetadata.PaginationConfigs.Where(o => !o.PaginationMatchEnum.HasFlag(PaginationMatchEnum.PrimaryMatch)).FirstOrDefault(o => PaginationPrimaryMatch(o, primaryOrder));
|
||||
if (sequenceFullMatchOrderConfig != null)
|
||||
{
|
||||
return new SequenceEnumeratorAsyncStreamMergeEngine<TEntity>(_streamMergeContext, sequenceFullMatchOrderConfig, _shardingPageManager.Current.RouteQueryResults, primaryOrder.IsAsc);
|
||||
}
|
||||
}
|
||||
var mergeEngine = DoOrderSequencePaginationEnumeratorStreamMergeEngine(shardingEntityType);
|
||||
|
||||
var sequencePrimaryMatchOrderConfig = paginationMetadata.PaginationConfigs.Where(o => o.PaginationMatchEnum.HasFlag(PaginationMatchEnum.PrimaryMatch)).FirstOrDefault(o => PaginationPrimaryMatch(o, primaryOrder));
|
||||
if (sequencePrimaryMatchOrderConfig != null)
|
||||
{
|
||||
return new SequenceEnumeratorAsyncStreamMergeEngine<TEntity>(_streamMergeContext, sequencePrimaryMatchOrderConfig, _shardingPageManager.Current.RouteQueryResults, primaryOrder.IsAsc);
|
||||
}
|
||||
if (mergeEngine != null)
|
||||
return mergeEngine;
|
||||
|
||||
//skip过大reserve skip
|
||||
if (paginationMetadata.EnableReverseShardingPage && _streamMergeContext.Take.GetValueOrDefault() > 0)
|
||||
{
|
||||
var total = _shardingPageManager.Current.RouteQueryResults.Sum(o => o.QueryResult);
|
||||
if (paginationMetadata.IsUseReverse(_streamMergeContext.Skip.GetValueOrDefault(), total))
|
||||
{
|
||||
return new ReverseShardingEnumeratorAsyncStreamMergeEngine<TEntity>( _streamMergeContext, total);
|
||||
}
|
||||
}
|
||||
|
||||
//if (paginationMetadata.EnableUnevenShardingPage)
|
||||
//{
|
||||
|
@ -104,10 +86,136 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
|
|||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new DefaultShardingEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity>(_streamMergeContext);
|
||||
}
|
||||
|
||||
private IEnumeratorStreamMergeEngine<TEntity> DoNoOrderAppendEnumeratorStreamMergeEngine(Type shardingEntityType)
|
||||
{
|
||||
|
||||
var isShardingDataSource = shardingEntityType.IsShardingDataSource();
|
||||
var isShardingTable = shardingEntityType.IsShardingTable();
|
||||
PaginationSequenceConfig dataSourceSequenceOrderConfig = null;
|
||||
PaginationSequenceConfig tableSequenceOrderConfig = null;
|
||||
if (isShardingDataSource)
|
||||
{
|
||||
var virtualDataSourceRoute = _virtualDataSource.GetRoute(shardingEntityType);
|
||||
if (virtualDataSourceRoute.EnablePagination)
|
||||
{
|
||||
dataSourceSequenceOrderConfig = virtualDataSourceRoute.PaginationMetadata.PaginationConfigs.OrderByDescending(o => o.AppendOrder)
|
||||
.FirstOrDefault(o => o.AppendIfOrderNone && typeof(TEntity).ContainPropertyName(o.PropertyName) && PaginationMatch(o));
|
||||
}
|
||||
|
||||
}
|
||||
if (isShardingTable)
|
||||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntityType);
|
||||
if (virtualTable.EnablePagination)
|
||||
{
|
||||
tableSequenceOrderConfig = virtualTable.PaginationMetadata.PaginationConfigs.OrderByDescending(o => o.AppendOrder)
|
||||
.FirstOrDefault(o => o.AppendIfOrderNone && typeof(TEntity).ContainPropertyName(o.PropertyName) && PaginationMatch(o));
|
||||
}
|
||||
}
|
||||
if (dataSourceSequenceOrderConfig != null || tableSequenceOrderConfig != null)
|
||||
{
|
||||
return new AppenOrderSequenceEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity>(_streamMergeContext, dataSourceSequenceOrderConfig, tableSequenceOrderConfig, _shardingPageManager.Current.RouteQueryResults);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private IEnumeratorStreamMergeEngine<TEntity> DoOrderSequencePaginationEnumeratorStreamMergeEngine(Type shardingEntityType)
|
||||
{
|
||||
|
||||
var orderCount = _streamMergeContext.Orders.Count();
|
||||
var primaryOrder = _streamMergeContext.Orders.First();
|
||||
var isShardingDataSource = shardingEntityType.IsShardingDataSource();
|
||||
var isShardingTable = shardingEntityType.IsShardingTable();
|
||||
PaginationSequenceConfig dataSourceSequenceOrderConfig = null;
|
||||
PaginationSequenceConfig tableSequenceOrderConfig = null;
|
||||
IVirtualDataSourceRoute virtualDataSourceRoute = null;
|
||||
IVirtualTable virtualTable = null;
|
||||
bool dataSourceUseReverse = true;
|
||||
bool tableUseReverse = true;
|
||||
if (isShardingDataSource)
|
||||
{
|
||||
virtualDataSourceRoute = _virtualDataSource.GetRoute(shardingEntityType);
|
||||
if (virtualDataSourceRoute.EnablePagination)
|
||||
{
|
||||
dataSourceSequenceOrderConfig = orderCount == 1 ? GetPaginationFullMatch(virtualDataSourceRoute.PaginationMetadata.PaginationConfigs, primaryOrder) : GetPaginationPrimaryMatch(virtualDataSourceRoute.PaginationMetadata.PaginationConfigs, primaryOrder);
|
||||
}
|
||||
|
||||
}
|
||||
if (isShardingTable)
|
||||
{
|
||||
virtualTable = _virtualTableManager.GetVirtualTable(shardingEntityType);
|
||||
if (virtualTable.EnablePagination)
|
||||
{
|
||||
tableSequenceOrderConfig = orderCount == 1 ? GetPaginationFullMatch(virtualTable.PaginationMetadata.PaginationConfigs, primaryOrder) : GetPaginationPrimaryMatch(virtualTable.PaginationMetadata.PaginationConfigs, primaryOrder);
|
||||
}
|
||||
}
|
||||
if (dataSourceSequenceOrderConfig != null || tableSequenceOrderConfig != null)
|
||||
{
|
||||
return new SequenceEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity>(_streamMergeContext, dataSourceSequenceOrderConfig, tableSequenceOrderConfig, _shardingPageManager.Current.RouteQueryResults, primaryOrder.IsAsc);
|
||||
}
|
||||
|
||||
var total = _shardingPageManager.Current.RouteQueryResults.Sum(o => o.QueryResult);
|
||||
if (isShardingDataSource&& virtualDataSourceRoute.EnablePagination)
|
||||
{
|
||||
dataSourceUseReverse =
|
||||
EntityDataSourceUseReverseShardingPage(virtualDataSourceRoute, total);
|
||||
}
|
||||
if (isShardingTable && virtualTable.EnablePagination)
|
||||
{
|
||||
tableUseReverse =
|
||||
EntityTableReverseShardingPage(virtualTable, total);
|
||||
}
|
||||
|
||||
|
||||
return new DefaultShardingEnumeratorAsyncStreamMergeEngine<TEntity>(_streamMergeContext);
|
||||
//skip过大reserve skip
|
||||
if (dataSourceUseReverse && tableUseReverse)
|
||||
{
|
||||
return new ReverseShardingEnumeratorAsyncStreamMergeEngine<TEntity>(_streamMergeContext, total);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool EntityDataSourceUseReverseShardingPage( IVirtualDataSourceRoute virtualDataSourceRoute,long total)
|
||||
{
|
||||
if (virtualDataSourceRoute.PaginationMetadata.EnableReverseShardingPage && _streamMergeContext.Take.GetValueOrDefault() > 0)
|
||||
{
|
||||
if (virtualDataSourceRoute.PaginationMetadata.IsUseReverse(_streamMergeContext.Skip.GetValueOrDefault(), total))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private bool EntityTableReverseShardingPage( IVirtualTable virtualTable, long total)
|
||||
{
|
||||
if (virtualTable.PaginationMetadata.EnableReverseShardingPage && _streamMergeContext.Take.GetValueOrDefault() > 0)
|
||||
{
|
||||
if (virtualTable.PaginationMetadata.IsUseReverse(_streamMergeContext.Skip.GetValueOrDefault(), total))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private PaginationSequenceConfig GetPaginationFullMatch(ISet<PaginationSequenceConfig> paginationSequenceConfigs, PropertyOrder primaryOrder)
|
||||
{
|
||||
return paginationSequenceConfigs.Where(o => !o.PaginationMatchEnum.HasFlag(PaginationMatchEnum.PrimaryMatch)).FirstOrDefault(o => PaginationPrimaryMatch(o, primaryOrder));
|
||||
}
|
||||
private PaginationSequenceConfig GetPaginationPrimaryMatch(ISet<PaginationSequenceConfig> paginationSequenceConfigs, PropertyOrder primaryOrder)
|
||||
{
|
||||
return paginationSequenceConfigs.Where(o => o.PaginationMatchEnum.HasFlag(PaginationMatchEnum.PrimaryMatch)).FirstOrDefault(o => PaginationPrimaryMatch(o, primaryOrder));
|
||||
}
|
||||
|
||||
private bool PaginationMatch(PaginationSequenceConfig paginationSequenceConfig)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.Internal.StreamMerge.ReWrite;
|
||||
using ShardingCore.Core.Internal.Visitors;
|
||||
|
@ -39,6 +40,10 @@ namespace ShardingCore.Sharding
|
|||
public GroupByContext GroupByContext { get; }
|
||||
public IEnumerable<TableRouteResult> TableRouteResults { get; }
|
||||
public DataSourceRouteResult DataSourceRouteResult { get; }
|
||||
/// <summary>
|
||||
/// 本次查询涉及的对象
|
||||
/// </summary>
|
||||
public ISet<Type> QueryEntities { get; }
|
||||
|
||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,
|
||||
DataSourceRouteResult dataSourceRouteResult,
|
||||
|
@ -56,6 +61,7 @@ namespace ShardingCore.Sharding
|
|||
SelectContext = reWriteResult.SelectContext;
|
||||
GroupByContext = reWriteResult.GroupByContext;
|
||||
_reWriteSource = reWriteResult.ReWriteQueryable;
|
||||
QueryEntities = source.ParseQueryableRoute();
|
||||
DataSourceRouteResult = dataSourceRouteResult;
|
||||
TableRouteResults= tableRouteResults;
|
||||
//RouteResults = _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
|
||||
|
|
|
@ -2,6 +2,8 @@ using ShardingCore.Sharding.ShardingQueryExecutors;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines
|
||||
{
|
||||
|
@ -11,7 +13,8 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
* @Date: Saturday, 14 August 2021 22:07:28
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class AsyncEnumerableStreamMergeEngine<T> : IAsyncEnumerable<T>, IEnumerable<T>
|
||||
public class AsyncEnumerableStreamMergeEngine<TShardingDbContext,T> : IAsyncEnumerable<T>, IEnumerable<T>
|
||||
where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
private readonly StreamMergeContext<T> _mergeContext;
|
||||
|
||||
|
@ -24,7 +27,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
#if !EFCORE2
|
||||
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return new EnumeratorShardingQueryExecutor<T>(_mergeContext).ExecuteAsync(cancellationToken)
|
||||
return new EnumeratorShardingQueryExecutor<TShardingDbContext,T>(_mergeContext).ExecuteAsync(cancellationToken)
|
||||
.GetAsyncEnumerator(cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
@ -32,7 +35,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
#if EFCORE2
|
||||
IAsyncEnumerator<T> IAsyncEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
return ((IAsyncEnumerable<T>)new EnumeratorShardingQueryExecutor<T>(_mergeContext).ExecuteAsync())
|
||||
return ((IAsyncEnumerable<T>)new EnumeratorShardingQueryExecutor<TShardingDbContext,T>(_mergeContext).ExecuteAsync())
|
||||
.GetEnumerator();
|
||||
}
|
||||
#endif
|
||||
|
@ -41,7 +44,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
|
||||
return ((IEnumerable<T>)new EnumeratorShardingQueryExecutor<T>(_mergeContext).ExecuteAsync())
|
||||
return ((IEnumerable<T>)new EnumeratorShardingQueryExecutor<TShardingDbContext,T>(_mergeContext).ExecuteAsync())
|
||||
.GetEnumerator();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,12 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.Internal.Visitors;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
@ -21,13 +24,16 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class AppenOrderSequenceEnumeratorAsyncStreamMergeEngine<TEntity> : AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
public class AppenOrderSequenceEnumeratorAsyncStreamMergeEngine<TShardingDbContext,TEntity> : AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly PaginationSequenceConfig _appendPaginationSequenceConfig;
|
||||
private readonly PaginationSequenceConfig _dataSourceSequenceOrderConfig;
|
||||
private readonly PaginationSequenceConfig _tableSequenceOrderConfig;
|
||||
private readonly ICollection<RouteQueryResult<long>> _routeQueryResults;
|
||||
public AppenOrderSequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext, PaginationSequenceConfig appendPaginationSequenceConfig, ICollection<RouteQueryResult<long>> routeQueryResults) : base(streamMergeContext)
|
||||
public AppenOrderSequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext, PaginationSequenceConfig dataSourceSequenceOrderConfig, PaginationSequenceConfig tableSequenceOrderConfig, ICollection<RouteQueryResult<long>> routeQueryResults) : base(streamMergeContext)
|
||||
{
|
||||
_appendPaginationSequenceConfig = appendPaginationSequenceConfig;
|
||||
_dataSourceSequenceOrderConfig = dataSourceSequenceOrderConfig;
|
||||
_tableSequenceOrderConfig = tableSequenceOrderConfig;
|
||||
_routeQueryResults = routeQueryResults;
|
||||
}
|
||||
|
||||
|
@ -44,17 +50,60 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
|
||||
var sortRouteResults = _routeQueryResults.Select(o => new
|
||||
{
|
||||
DataSourceName=o.DataSourceName,
|
||||
Tail = o.TableRouteResult.ReplaceTables.First().Tail,
|
||||
RouteQueryResult = o
|
||||
}).OrderBy(o => o.Tail, _appendPaginationSequenceConfig.TailComparer).ToList();
|
||||
var skipCount = skip;
|
||||
});
|
||||
|
||||
//分库是主要排序
|
||||
var dataSourceOrderMain = _dataSourceSequenceOrderConfig != null;
|
||||
var reSetOrders = new List<PropertyOrder>();
|
||||
if (dataSourceOrderMain)
|
||||
{
|
||||
//if sharding data source
|
||||
var appendAsc = _dataSourceSequenceOrderConfig.AppendAsc;
|
||||
//if sharding table
|
||||
var useThenBy = dataSourceOrderMain && _tableSequenceOrderConfig != null;
|
||||
if (appendAsc)
|
||||
{
|
||||
sortRouteResults = sortRouteResults.OrderBy(o => o.DataSourceName,
|
||||
_dataSourceSequenceOrderConfig.RouteComparer)
|
||||
.ThenByIf(o => o.Tail, useThenBy&& _tableSequenceOrderConfig.AppendAsc, _tableSequenceOrderConfig.RouteComparer)
|
||||
.ThenByDescendingIf(o => o.Tail, useThenBy&& !_tableSequenceOrderConfig.AppendAsc, _tableSequenceOrderConfig.RouteComparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortRouteResults = sortRouteResults.OrderByDescending(o => o.DataSourceName,
|
||||
_dataSourceSequenceOrderConfig.RouteComparer).ThenByDescendingIf(o => o.Tail, useThenBy, _tableSequenceOrderConfig.RouteComparer);
|
||||
}
|
||||
reSetOrders.Add(new PropertyOrder(_dataSourceSequenceOrderConfig.PropertyName, _dataSourceSequenceOrderConfig.AppendAsc));
|
||||
if (useThenBy)
|
||||
{
|
||||
reSetOrders.Add(new PropertyOrder(_tableSequenceOrderConfig.PropertyName, _tableSequenceOrderConfig.AppendAsc));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var appendAsc = _tableSequenceOrderConfig.AppendAsc;
|
||||
|
||||
if (appendAsc)
|
||||
{
|
||||
sortRouteResults = sortRouteResults.OrderBy(o => o.Tail, _tableSequenceOrderConfig.RouteComparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortRouteResults =
|
||||
sortRouteResults.OrderByDescending(o => o.Tail, _tableSequenceOrderConfig.RouteComparer);
|
||||
}
|
||||
reSetOrders.Add(new PropertyOrder(_tableSequenceOrderConfig.PropertyName, _tableSequenceOrderConfig.AppendAsc));
|
||||
}
|
||||
|
||||
var sequenceResults = new SequencePaginationList(sortRouteResults.Select(o=>o.RouteQueryResult)).Skip(skip).Take(take).ToList();
|
||||
|
||||
StreamMergeContext.ReSetOrders(new [] { new PropertyOrder(_appendPaginationSequenceConfig.PropertyName, true) });
|
||||
StreamMergeContext.ReSetOrders(reSetOrders);
|
||||
var enumeratorTasks = sequenceResults.Select(sequenceResult =>
|
||||
{
|
||||
var newQueryable = CreateAsyncExecuteQueryable(sequenceResult.DSName,noPaginationQueryable, sequenceResult);
|
||||
var newQueryable = CreateAsyncExecuteQueryable(sequenceResult.DSName,noPaginationQueryable, sequenceResult, reSetOrders);
|
||||
return AsyncQueryEnumerator(newQueryable,async);
|
||||
}).ToArray();
|
||||
|
||||
|
@ -62,11 +111,11 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
return streamEnumerators;
|
||||
}
|
||||
|
||||
private IQueryable<TEntity> CreateAsyncExecuteQueryable(string dsname,IQueryable<TEntity> noPaginationQueryable, SequenceResult sequenceResult)
|
||||
private IQueryable<TEntity> CreateAsyncExecuteQueryable(string dsname,IQueryable<TEntity> noPaginationQueryable, SequenceResult sequenceResult,IEnumerable<PropertyOrder> reSetOrders)
|
||||
{
|
||||
var shardingDbContext = StreamMergeContext.CreateDbContext(dsname,sequenceResult.TableRouteResult);
|
||||
DbContextQueryStore.TryAdd(sequenceResult.TableRouteResult, shardingDbContext);
|
||||
var newQueryable = (IQueryable<TEntity>)(noPaginationQueryable.Skip(sequenceResult.Skip).Take(sequenceResult.Take).OrderWithExpression(new PropertyOrder[]{new PropertyOrder(_appendPaginationSequenceConfig.PropertyName,true)}))
|
||||
var newQueryable = (IQueryable<TEntity>)(noPaginationQueryable.Skip(sequenceResult.Skip).Take(sequenceResult.Take).OrderWithExpression(reSetOrders))
|
||||
.ReplaceDbContextQueryable(shardingDbContext);
|
||||
return newQueryable;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
|
||||
using ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.Abstractions;
|
||||
|
@ -16,7 +18,8 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DefaultShardingEnumeratorAsyncStreamMergeEngine<TEntity>:AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
public class DefaultShardingEnumeratorAsyncStreamMergeEngine<TShardingDbContext,TEntity> :AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public DefaultShardingEnumeratorAsyncStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext) : base(streamMergeContext)
|
||||
{
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.Internal.Visitors;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
|
||||
using ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.Abstractions;
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
@ -20,14 +22,17 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class SequenceEnumeratorAsyncStreamMergeEngine<TEntity> : AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
public class SequenceEnumeratorAsyncStreamMergeEngine<TShardingDbContext,TEntity> : AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly PaginationSequenceConfig _orderPaginationSequenceConfig;
|
||||
private readonly PaginationSequenceConfig _dataSourceSequenceMatchOrderConfig;
|
||||
private readonly PaginationSequenceConfig _tableSequenceMatchOrderConfig;
|
||||
private readonly ICollection<RouteQueryResult<long>> _routeQueryResults;
|
||||
private readonly bool _isAsc;
|
||||
public SequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext, PaginationSequenceConfig orderPaginationSequenceConfig, ICollection<RouteQueryResult<long>> routeQueryResults, bool isAsc) : base(streamMergeContext)
|
||||
public SequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext, PaginationSequenceConfig dataSourceSequenceMatchOrderConfig, PaginationSequenceConfig tableSequenceMatchOrderConfig, ICollection<RouteQueryResult<long>> routeQueryResults, bool isAsc) : base(streamMergeContext)
|
||||
{
|
||||
_orderPaginationSequenceConfig = orderPaginationSequenceConfig;
|
||||
_dataSourceSequenceMatchOrderConfig = dataSourceSequenceMatchOrderConfig;
|
||||
_tableSequenceMatchOrderConfig = tableSequenceMatchOrderConfig;
|
||||
_routeQueryResults = routeQueryResults;
|
||||
_isAsc = isAsc;
|
||||
}
|
||||
|
@ -42,13 +47,43 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
var take = StreamMergeContext.Take;
|
||||
if (take.HasValue && take.Value <= 0)
|
||||
throw new ShardingCoreException("take must gt 0");
|
||||
|
||||
//分库是主要排序
|
||||
var dataSourceOrderMain = _dataSourceSequenceMatchOrderConfig != null;
|
||||
var sortRouteResults = _routeQueryResults.Select(o => new
|
||||
{
|
||||
DataSourceName=o.DataSourceName,
|
||||
Tail = o.TableRouteResult.ReplaceTables.First().Tail,
|
||||
RouteQueryResult = o
|
||||
}).OrderByIf(o => o.Tail, _isAsc, _orderPaginationSequenceConfig.TailComparer)
|
||||
.OrderByDescendingIf(o => o.Tail, !_isAsc, _orderPaginationSequenceConfig.TailComparer).ToList();
|
||||
});
|
||||
if (dataSourceOrderMain)
|
||||
{
|
||||
//是否有两级排序
|
||||
var useThenBy = dataSourceOrderMain && _tableSequenceMatchOrderConfig != null;
|
||||
if (_isAsc)
|
||||
{
|
||||
sortRouteResults = sortRouteResults.OrderBy(o => o.DataSourceName,
|
||||
_dataSourceSequenceMatchOrderConfig.RouteComparer).ThenByIf(o=>o.Tail, useThenBy, _tableSequenceMatchOrderConfig.RouteComparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortRouteResults = sortRouteResults.OrderByDescending(o => o.DataSourceName,
|
||||
_dataSourceSequenceMatchOrderConfig.RouteComparer).ThenByDescendingIf(o => o.Tail, useThenBy, _tableSequenceMatchOrderConfig.RouteComparer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isAsc)
|
||||
{
|
||||
sortRouteResults =
|
||||
sortRouteResults.OrderBy(o => o.Tail, _tableSequenceMatchOrderConfig.RouteComparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
sortRouteResults =
|
||||
sortRouteResults.OrderByDescending(o => o.Tail, _tableSequenceMatchOrderConfig.RouteComparer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var sequenceResults = new SequencePaginationList(sortRouteResults.Select(o => o.RouteQueryResult)).Skip(skip).Take(take).ToList();
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.Abstractions;
|
||||
|
||||
|
@ -12,7 +14,8 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
* @Date: Thursday, 02 September 2021 20:58:10
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class SingleQueryEnumeratorAsyncStreamMergeEngine<TEntity> : AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
public class SingleQueryEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity> : AbstractEnumeratorAsyncStreamMergeEngine<TEntity>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public SingleQueryEnumeratorAsyncStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext) : base(streamMergeContext)
|
||||
{
|
||||
|
@ -41,7 +44,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
public override IStreamMergeAsyncEnumerator<TEntity> GetStreamMergeAsyncEnumerator(IStreamMergeAsyncEnumerator<TEntity>[] streamsAsyncEnumerators)
|
||||
{
|
||||
if (streamsAsyncEnumerators.Length != 1)
|
||||
throw new ShardingCoreException($"{nameof(SingleQueryEnumeratorAsyncStreamMergeEngine<TEntity>)} has more {nameof(IStreamMergeAsyncEnumerator<TEntity>)}");
|
||||
throw new ShardingCoreException($"{nameof(SingleQueryEnumeratorAsyncStreamMergeEngine<TShardingDbContext,TEntity>)} has more {nameof(IStreamMergeAsyncEnumerator<TEntity>)}");
|
||||
return streamsAsyncEnumerators[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ namespace ShardingCore
|
|||
{
|
||||
var routeType = _shardingConfigOption.GetVirtualDataSourceRouteType(entityType);
|
||||
var virtualRoute = CreateVirtualDataSourceRoute(routeType);
|
||||
virtualRoute.Init();
|
||||
virtualDataSource.AddVirtualDataSourceRoute(virtualRoute);
|
||||
}
|
||||
if (entityType.IsShardingTable())
|
||||
|
|
|
@ -1,32 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
|
||||
namespace ShardingCore.VirtualRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Description:sharding table route by date time
|
||||
* @Date: Wednesday, 27 January 2021 12:29:19
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// time type is date time
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class AbstractShardingTimeKeyDateTimeVirtualTableRoute<T> : AbstractShardingOperatorVirtualTableRoute<T, DateTime> where T : class, IShardingTable
|
||||
{
|
||||
/// <summary>
|
||||
/// how convert object to date time
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
protected override DateTime ConvertToShardingKey(object shardingKey)
|
||||
{
|
||||
return Convert.ToDateTime(shardingKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// how convert sharding key to tail
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
public override string ShardingKeyToTail(object shardingKey)
|
||||
{
|
||||
var time = ConvertToShardingKey(shardingKey);
|
||||
return TimeFormatToTail(time);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// how format date time to tail
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract string TimeFormatToTail(DateTime time);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,31 +1,44 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
|
||||
namespace ShardingCore.VirtualRoutes.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Description: sharding table route by time stamp (ms)
|
||||
* @Date: Wednesday, 27 January 2021 13:06:01
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// sharding table route by time stamp (ms)
|
||||
/// </summary>
|
||||
/// <typeparam name="T">entity</typeparam>
|
||||
public abstract class AbstractShardingTimeKeyLongVirtualTableRoute<T> : AbstractShardingOperatorVirtualTableRoute<T, long> where T : class, IShardingTable
|
||||
{
|
||||
/// <summary>
|
||||
/// how convert object to long
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
protected override long ConvertToShardingKey(object shardingKey)
|
||||
{
|
||||
return (long)shardingKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// how convert sharding key to tail
|
||||
/// </summary>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
public override string ShardingKeyToTail(object shardingKey)
|
||||
{
|
||||
var time = ConvertToShardingKey(shardingKey);
|
||||
return TimeFormatToTail(time);
|
||||
}
|
||||
/// <summary>
|
||||
/// how format long time to tail
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract string TimeFormatToTail(long time);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.VirtualRoutes.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.VirtualRoutes.Abstractions;
|
||||
|
||||
namespace ShardingCore.VirtualRoutes.Days
|
||||
{
|
||||
|
@ -15,7 +15,15 @@ namespace ShardingCore.VirtualRoutes.Days
|
|||
*/
|
||||
public abstract class AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute<T>:AbstractShardingTimeKeyDateTimeVirtualTableRoute<T> where T:class,IShardingTable
|
||||
{
|
||||
/// <summary>
|
||||
/// begin time use fixed time eg.new DateTime(20xx,xx,xx)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract DateTime GetBeginTime();
|
||||
/// <summary>
|
||||
/// return all tails in database
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override List<string> GetAllTails()
|
||||
{
|
||||
var beginTime = GetBeginTime();
|
||||
|
@ -24,7 +32,7 @@ namespace ShardingCore.VirtualRoutes.Days
|
|||
//提前创建表
|
||||
var nowTimeStamp = DateTime.Now.AddDays(1).Date;
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ShardingCore.VirtualRoutes.Days
|
|||
//提前创建表
|
||||
var nowTimeStamp = DateTime.Now.AddDays(1).Date;
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
|
||||
namespace ShardingCore.VirtualRoutes.Mods
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Helpers;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.VirtualRoutes.Months
|
|||
//提前创建表
|
||||
var nowTimeStamp =ShardingCoreHelper.GetNextMonthFirstDay(DateTime.Now);
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.VirtualRoutes.Months
|
|||
//提前创建表
|
||||
var nowTimeStamp =ShardingCoreHelper.GetNextMonthFirstDay(DateTime.Now);
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.VirtualRoutes.Weeks
|
|||
//提前创建表
|
||||
var nowTimeStamp = DateTime.Now.AddDays(7).Date;
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.VirtualRoutes.Weeks
|
|||
//提前创建表
|
||||
var nowTimeStamp = DateTime.Now.AddDays(7).Date;
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.VirtualRoutes.Abstractions;
|
||||
|
||||
namespace ShardingCore.VirtualRoutes.Years
|
||||
|
@ -25,7 +24,7 @@ namespace ShardingCore.VirtualRoutes.Years
|
|||
//提前创建表
|
||||
var nowTimeStamp = DateTime.Now.AddYears(1).Date;
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.VirtualRoutes.Years
|
|||
//提前创建表
|
||||
var nowTimeStamp = DateTime.Now.AddYears(1).Date;
|
||||
if (beginTime > nowTimeStamp)
|
||||
throw new ArgumentException("起始时间不正确无法生成正确的表名");
|
||||
throw new ArgumentException("begin time error");
|
||||
var currentTimeStamp = beginTime;
|
||||
while (currentTimeStamp <= nowTimeStamp)
|
||||
{
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace ShardingCore.Test50
|
|||
{
|
||||
using (_shardingRouteManager.CreateScope())
|
||||
{
|
||||
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
|
||||
_shardingRouteManager.Current.MustTable.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
|
||||
|
||||
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
|
||||
Assert.Equal(333, mod00s.Count);
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Test50.Domain.Entities;
|
||||
using ShardingCore.VirtualRoutes;
|
||||
using ShardingCore.VirtualRoutes.Mods;
|
||||
|
||||
namespace ShardingCore.Test50.Shardings
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace ShardingCore.Test50_2x
|
|||
{
|
||||
using (_shardingRouteManager.CreateScope())
|
||||
{
|
||||
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
|
||||
_shardingRouteManager.Current.MustTable.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
|
||||
|
||||
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
|
||||
Assert.Equal(333, mod00s.Count);
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace ShardingCore.Test50_3x
|
|||
{
|
||||
using (_shardingRouteManager.CreateScope())
|
||||
{
|
||||
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
|
||||
_shardingRouteManager.Current.MustTable.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
|
||||
|
||||
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
|
||||
Assert.Equal(333, mod00s.Count);
|
||||
|
|
Loading…
Reference in New Issue