diff --git a/samples/Sample.SqlServer/Shardings/SysUserSalaryPaginationConfiguration.cs b/samples/Sample.SqlServer/Shardings/SysUserSalaryPaginationConfiguration.cs index aca03b68..3a937d25 100644 --- a/samples/Sample.SqlServer/Shardings/SysUserSalaryPaginationConfiguration.cs +++ b/samples/Sample.SqlServer/Shardings/SysUserSalaryPaginationConfiguration.cs @@ -12,7 +12,7 @@ namespace Sample.SqlServer.Shardings public void Configure(PaginationBuilder builder) { builder.PaginationSequence(o => o.Id) - .UseTailComparer(Comparer.Default) + .UseRouteComparer(Comparer.Default) .UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch); builder.PaginationSequence(o => o.DateOfMonth) .UseQueryMatch(PaginationMatchEnum.Owner | PaginationMatchEnum.Named | PaginationMatchEnum.PrimaryMatch).UseAppendIfOrderNone(10); diff --git a/src/ShardingCore/Core/QueryRouteManagers/Abstractions/IDataSourceRouteAssert.cs b/src/ShardingCore/Core/QueryRouteManagers/Abstractions/IDataSourceRouteAssert.cs new file mode 100644 index 00000000..96cebf09 --- /dev/null +++ b/src/ShardingCore/Core/QueryRouteManagers/Abstractions/IDataSourceRouteAssert.cs @@ -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 + */ + /// + /// 路由断言 + /// + public interface IDataSourceRouteAssert + { + /// + /// 断言路由结果 + /// + /// 所有的路由数据源 + /// 本次查询路由返回结果 + void Assert(List allDataSources, List resultDataSources); + } + + public interface IDataSourceRouteAssert : IDataSourceRouteAssert where T : class, IShardingDataSource + { + + } +} diff --git a/src/ShardingCore/Core/QueryRouteManagers/Abstractions/IRouteAssert.cs b/src/ShardingCore/Core/QueryRouteManagers/Abstractions/ITableRouteAssert.cs similarity index 76% rename from src/ShardingCore/Core/QueryRouteManagers/Abstractions/IRouteAssert.cs rename to src/ShardingCore/Core/QueryRouteManagers/Abstractions/ITableRouteAssert.cs index 545f8d70..97d58882 100644 --- a/src/ShardingCore/Core/QueryRouteManagers/Abstractions/IRouteAssert.cs +++ b/src/ShardingCore/Core/QueryRouteManagers/Abstractions/ITableRouteAssert.cs @@ -13,12 +13,12 @@ namespace ShardingCore.Core.QueryRouteManagers.Abstractions /// /// 路由断言 /// - public interface IRouteAssert + public interface ITableRouteAssert { void Assert(List allPhysicTables, List resultPhysicTables); } - public interface IRouteAssert : IRouteAssert where T : class, IShardingTable + public interface ITableRouteAssert : ITableRouteAssert where T : class,IShardingTable { } diff --git a/src/ShardingCore/Core/QueryRouteManagers/ShardingRouteContext.cs b/src/ShardingCore/Core/QueryRouteManagers/ShardingRouteContext.cs index d76bfba1..cb7358cd 100644 --- a/src/ShardingCore/Core/QueryRouteManagers/ShardingRouteContext.cs +++ b/src/ShardingCore/Core/QueryRouteManagers/ShardingRouteContext.cs @@ -16,23 +16,43 @@ namespace ShardingCore.Core.QueryRouteManagers */ public class ShardingRouteContext { + #region 分库提示路由 /// /// 强制路由直接返回对应的后缀表 /// - public Dictionary> Must { get; } + public Dictionary> MustDataSource { get; } /// /// 提示路由会经过断言的强制路由 /// - public Dictionary> Hint { get; } + public Dictionary> HintDataSource { get; } /// /// 断言 /// - public Dictionary> Assert { get; } + public Dictionary> AssertDataSource { get; } + #endregion + + #region 分表提示路由 + /// + /// 强制路由直接返回对应的后缀表 + /// + public Dictionary> MustTable { get; } + /// + /// 提示路由会经过断言的强制路由 + /// + public Dictionary> HintTable { get; } + /// + /// 断言 + /// + public Dictionary> AssertTable { get; } + #endregion private ShardingRouteContext() { - Must = new Dictionary>(); - Hint = new Dictionary>(); - Assert = new Dictionary>(); + MustDataSource = new Dictionary>(); + HintDataSource = new Dictionary>(); + AssertDataSource = new Dictionary>(); + MustTable = new Dictionary>(); + HintTable = new Dictionary>(); + AssertTable = new Dictionary>(); } public static ShardingRouteContext Create() diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs index 869a384c..f0b02604 100644 --- a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs +++ b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/IVirtualDataSource.cs @@ -22,10 +22,11 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources where TShardingDbContext : DbContext, IShardingDbContext { string DefaultDataSourceName { get; } - /// /// 路由到具体的物理数据源 /// + /// + /// /// data source names List RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig); diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs index 939eb902..204c9d9a 100644 --- a/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs +++ b/src/ShardingCore/Core/VirtualDatabase/VirtualDataSources/VirtualDataSource.cs @@ -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); } } } \ No newline at end of file diff --git a/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs b/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs index 8532af4e..e65a20a2 100644 --- a/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs +++ b/src/ShardingCore/Core/VirtualDatabase/VirtualTables/DefaultVirtualTable.cs @@ -40,6 +40,7 @@ namespace ShardingCore.Core.VirtualTables /// 分库配置 /// public PaginationMetadata PaginationMetadata { get; } + /// /// 是否启用智能分页 /// @@ -54,7 +55,7 @@ namespace ShardingCore.Core.VirtualTables EntityType = typeof(T); ShardingConfig = ShardingUtil.Parse(EntityType); var paginationConfiguration = virtualTableRoute.CreatePaginationConfiguration(); - if (paginationConfiguration != null) + if (paginationConfiguration!=null) { PaginationMetadata = new PaginationMetadata(); var paginationBuilder = new PaginationBuilder(PaginationMetadata); diff --git a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingFilterVirtualDataSourceRoute.cs b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingFilterVirtualDataSourceRoute.cs new file mode 100644 index 00000000..08185e73 --- /dev/null +++ b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingFilterVirtualDataSourceRoute.cs @@ -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 + */ + /// + /// 过滤虚拟路由用于处理强制路由、提示路由、路由断言 + /// + /// + /// + public abstract class AbstractShardingFilterVirtualDataSourceRoute : AbstractVirtualDataSourceRoute where T : class, IShardingDataSource + { + public ShardingRouteContext CurrentShardingRouteContext => + ShardingContainer.GetService().Current; + /// + /// 启用提示路由 + /// + protected virtual bool EnableHintRoute => false; + /// + /// 启用断言路由 + /// + protected virtual bool EnableAssertRoute => false; + public override List RouteWithPredicate(IQueryable queryable,bool isQuery) + { + var allDataSourceNames = GetAllDataSourceNames(); + if (!isQuery) + { + //后拦截器 + return AfterDataSourceFilter(allDataSourceNames, DoRouteWithPredicate(allDataSourceNames, queryable)); + } + //强制路由不经过断言 + if (EnableHintRoute) + { + if (CurrentShardingRouteContext != null) + { + if (CurrentShardingRouteContext.TryGetMustDataSource(out HashSet 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(out HashSet 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 allDataSources,List filterDataSources) + { + if (EnableAssertRoute) + { + if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertDataSource(out ICollection routeAsserts) && routeAsserts.IsNotEmpty()) + { + foreach (var routeAssert in routeAsserts) + { + routeAssert.Assert(allDataSources, filterDataSources); + } + } + } + } + + protected abstract List DoRouteWithPredicate(List allDataSourceNames, IQueryable queryable); + + + /// + /// 物理表过滤后 + /// + /// 所有的物理表 + /// 过滤后的物理表 + /// + protected virtual List AfterDataSourceFilter(List allDataSourceNames, List filterDataSources) + { + return filterDataSources; + } + } +} \ No newline at end of file diff --git a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs new file mode 100644 index 00000000..858c3e93 --- /dev/null +++ b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs @@ -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 + */ + /// + /// 抽象类型抽象出对应的条件表达式 + /// + /// + /// + public abstract class AbstractShardingOperatorVirtualDataSourceRoute : AbstractShardingFilterVirtualDataSourceRoute where T : class, IShardingDataSource + { + + protected override List DoRouteWithPredicate(List allDataSourceNames, IQueryable queryable) + { + //获取所有需要路由的表后缀 + var filter = ShardingUtil.GetRouteShardingTableFilter(queryable, ShardingUtil.Parse(typeof(T)), ConvertToShardingKey, GetRouteToFilter); + var dataSources = allDataSourceNames.Where(o => filter(o)).ToList(); + return dataSources; + } + + + /// + /// 如何路由到具体表 shardingKeyValue:分表的值, 返回结果:如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表 + /// + /// 分表的值 + /// 操作 + /// 如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表 + protected abstract Expression> 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]; + } + } +} \ No newline at end of file diff --git a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractVirtualDataSourceRoute.cs b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractVirtualDataSourceRoute.cs new file mode 100644 index 00000000..6b04bdbf --- /dev/null +++ b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractVirtualDataSourceRoute.cs @@ -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 : IVirtualDataSourceRoute where T : class, IShardingDataSource + { + public void Init() + { + var paginationConfiguration = CreatePaginationConfiguration(); + if (paginationConfiguration != null) + { + PaginationMetadata = new PaginationMetadata(); + var paginationBuilder = new PaginationBuilder(PaginationMetadata); + paginationConfiguration.Configure(paginationBuilder); + } + } + public virtual IPaginationConfiguration CreatePaginationConfiguration() + { + return null; + } + /// + /// entity type + /// + public Type ShardingEntityType => typeof(T); + + public new PaginationMetadata PaginationMetadata { get; protected set; } + public bool EnablePagination => PaginationMetadata != null; + + /// + /// 分库字段object类型的如何转成对应的泛型类型how convert sharding key to generic type key value + /// + /// + /// + protected abstract TKey ConvertToShardingKey(object shardingKey); + /// + /// 分库字段如何转成对应的数据源名称 how convert sharding data source key to data source name + /// + /// + /// + public abstract string ShardingKeyToDataSourceName(object shardingKey); + + /// + /// 根据表达式返回对应的数据源名称 find data source names with queryable + /// + /// + /// + /// + public abstract List RouteWithPredicate(IQueryable queryable, bool isQuery); + /// + /// 值如何转成对应的数据源 + /// + /// + /// + public abstract string RouteWithValue(object shardingKey); + + public abstract List GetAllDataSourceNames(); + public abstract bool AddDataSourceName(string dataSourceName); + } +} \ No newline at end of file diff --git a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/IVirtualDataSourceRoute.cs b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/IVirtualDataSourceRoute.cs index ac4f8db1..fb703b73 100644 --- a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/IVirtualDataSourceRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/IVirtualDataSourceRoute.cs @@ -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;} + /// + /// 分页配置 + /// + PaginationMetadata PaginationMetadata { get; } + /// + /// 是否启用分页配置 + /// + bool EnablePagination { get; } string ShardingKeyToDataSourceName(object shardingKeyValue); /// /// 根据查询条件路由返回物理数据源 /// /// + /// /// data source name - List RouteWithWhere(IQueryable queryable); + List RouteWithPredicate(IQueryable queryable, bool isQuery); /// /// 根据值进行路由 @@ -31,10 +41,25 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes string RouteWithValue(object shardingKeyValue); List GetAllDataSourceNames(); + /// + /// 添加数据源 + /// + /// + /// + bool AddDataSourceName(string dataSourceName); + /// + /// 初始化 + /// + void Init(); } - public interface IVirtualDataSourceRoute : IVirtualDataSourceRoute where T : class + public interface IVirtualDataSourceRoute : IVirtualDataSourceRoute where T : class, IShardingDataSource { + /// + /// 返回null就是表示不开启分页配置 + /// + /// + IPaginationConfiguration CreatePaginationConfiguration(); } } \ No newline at end of file diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs index e8f23dad..a1f5a292 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingFilterVirtualTableRoute.cs @@ -81,7 +81,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions { if (EnableAssertRoute) { - if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertTail(out ICollection routeAsserts) && routeAsserts.IsNotEmpty()) + if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertTail(out ICollection routeAsserts) && routeAsserts.IsNotEmpty()) { foreach (var routeAssert in routeAsserts) { diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs index 6caef76b..f62e7ea6 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs @@ -38,7 +38,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions public override IPhysicTable RouteWithValue(List allPhysicTables, object shardingKey) { - var shardingKeyToTail = ShardingKeyToTail(ConvertToShardingKey(shardingKey)); + var shardingKeyToTail = ShardingKeyToTail(shardingKey); var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList(); if (physicTables.IsEmpty()) diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs index b9c042e5..0de27f33 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractVirtualTableRoute.cs @@ -51,9 +51,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions /// 根据值路由 /// /// - /// + /// /// - public abstract IPhysicTable RouteWithValue(List allPhysicTables, object shardingKeyValue); + public abstract IPhysicTable RouteWithValue(List allPhysicTables, object shardingKey); /// /// 返回数据库现有的尾巴 /// diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/IVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/IVirtualTableRoute.cs index 7ecad550..2faeeb54 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/IVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/IVirtualTableRoute.cs @@ -33,9 +33,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes /// 根据值进行路由 /// /// - /// + /// /// - IPhysicTable RouteWithValue(List allPhysicTables, object shardingKeyValue); + IPhysicTable RouteWithValue(List allPhysicTables, object shardingKey); /// /// 获取所有的目前数据库存在的尾巴 /// get all tails in the db diff --git a/src/ShardingCore/Extensions/InternalExtensions/InternalLinqExtension.cs b/src/ShardingCore/Extensions/InternalExtensions/InternalLinqExtension.cs index 80e087ce..9b417107 100644 --- a/src/ShardingCore/Extensions/InternalExtensions/InternalLinqExtension.cs +++ b/src/ShardingCore/Extensions/InternalExtensions/InternalLinqExtension.cs @@ -25,5 +25,15 @@ namespace ShardingCore.Extensions.InternalExtensions { return condition ? source.OrderByDescending(keySelector, comparer) : source; } + public static IOrderedEnumerable ThenByIf(this IOrderedEnumerable source, Func keySelector, bool condition, + IComparer? comparer) + { + return condition ? source.ThenBy(keySelector, comparer) : source; + } + public static IOrderedEnumerable ThenByDescendingIf(this IOrderedEnumerable source, Func keySelector, bool condition, + IComparer? comparer) + { + return condition ? source.ThenByDescending(keySelector, comparer) : source; + } } } diff --git a/src/ShardingCore/Extensions/ShardingDataSourceRouteExtension.cs b/src/ShardingCore/Extensions/ShardingDataSourceRouteExtension.cs new file mode 100644 index 00000000..1a02e823 --- /dev/null +++ b/src/ShardingCore/Extensions/ShardingDataSourceRouteExtension.cs @@ -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 + { + /// + /// 创建或者添加强制路由 + /// + /// + /// + /// + /// 任何一个dataSources被添加成功就返回成功 + public static bool TryCreateOrAddMustDataSource(this ShardingRouteContext shardingRouteContext, params string[] dataSources) where TEntity : class, IShardingDataSource + { + return TryCreateOrAddMustDataSource(shardingRouteContext, typeof(TEntity), dataSources); + } + /// + /// 创建或者添加强制路由 + /// + /// + /// + /// + /// 任何一个dataSources被添加成功就返回成功 + 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 mustDataSources)) + { + mustDataSources = new HashSet(); + shardingRouteContext.MustDataSource.Add(entityType, mustDataSources); + } + + return dataSources.Select(o => mustDataSources.Add(o)).Any(o => o); + } + /// + /// 创建或者添加提示路由 + /// + /// + /// + /// + /// 任何一个dataSources被添加成功就返回成功 + public static bool TryCreateOrAddHintDataSource(this ShardingRouteContext shardingRouteContext, params string[] dataSources) where TEntity : class, IShardingDataSource + { + return TryCreateOrAddHintDataSource(shardingRouteContext, typeof(TEntity), dataSources); + } + /// + /// 创建或者添加提示路由 + /// + /// + /// + /// + /// 任何一个dataSources被添加成功就返回成功 + 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 hintDataSources)) + { + hintDataSources = new HashSet(); + shardingRouteContext.HintDataSource.Add(entityType, hintDataSources); + } + + return dataSources.Select(o => hintDataSources.Add(o)).Any(o => o); + } + /// + /// 创建或者添加断言 + /// + /// + /// + /// + /// + public static bool TryCreateOrAddAssertDataSource(this ShardingRouteContext shardingRouteContext, params IDataSourceRouteAssert[] 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 routeAsserts)) + { + routeAsserts = new LinkedList(); + shardingRouteContext.AssertDataSource.Add(entityType, routeAsserts); + } + foreach (var routeAssert in asserts) + { + routeAsserts.AddLast(routeAssert); + } + + return true; + } + + + + public static bool TryGetMustDataSource(this ShardingRouteContext shardingRouteContext, out HashSet dataSources) where TEntity : class, IShardingDataSource + { + return TryGetMustDataSource(shardingRouteContext,typeof(TEntity),out dataSources); + } + public static bool TryGetMustDataSource(this ShardingRouteContext shardingRouteContext,Type entityType, out HashSet 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(this ShardingRouteContext shardingRouteContext, out HashSet dataSources) where TEntity : class,IShardingDataSource + { + return TryGetHintDataSource(shardingRouteContext,typeof(TEntity),out dataSources); + } + public static bool TryGetHintDataSource(this ShardingRouteContext shardingRouteContext,Type entityType, out HashSet 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(this ShardingRouteContext shardingRouteContext, out ICollection dataSources)where TEntity : class,IShardingDataSource + { + return TryGetAssertDataSource(shardingRouteContext,typeof(TEntity), out dataSources); + } + public static bool TryGetAssertDataSource(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection 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; + } + + } +} diff --git a/src/ShardingCore/Extensions/ShardingRouteExtension.cs b/src/ShardingCore/Extensions/ShardingTableRouteExtension.cs similarity index 82% rename from src/ShardingCore/Extensions/ShardingRouteExtension.cs rename to src/ShardingCore/Extensions/ShardingTableRouteExtension.cs index c161a091..666a6b28 100644 --- a/src/ShardingCore/Extensions/ShardingRouteExtension.cs +++ b/src/ShardingCore/Extensions/ShardingTableRouteExtension.cs @@ -16,7 +16,7 @@ namespace ShardingCore.Extensions * @Ver: 1.0 * @Email: 326308290@qq.com */ - public static class ShardingRouteExtension + public static class ShardingTableRouteExtension { /// /// 创建或者添加强制路由 @@ -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 mustTails)) + if (!shardingRouteContext.MustTable.TryGetValue(entityType,out HashSet mustTails)) { mustTails = new HashSet(); - 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 hintTails)) + if (!shardingRouteContext.HintTable.TryGetValue(entityType, out HashSet hintTails)) { hintTails = new HashSet(); - 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 /// /// /// - public static bool TryCreateOrAddAssertTail(this ShardingRouteContext shardingRouteContext, params IRouteAssert[] tails) where TEntity : class, IShardingTable + public static bool TryCreateOrAddAssertTail(this ShardingRouteContext shardingRouteContext, params ITableRouteAssert[] 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 routeAsserts)) + if (!shardingRouteContext.AssertTable.TryGetValue(entityType, out LinkedList routeAsserts)) { - routeAsserts = new LinkedList(); - shardingRouteContext.Assert.Add(entityType, routeAsserts); + routeAsserts = new LinkedList(); + 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(this ShardingRouteContext shardingRouteContext, out HashSet 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(this ShardingRouteContext shardingRouteContext, out ICollection tail)where TEntity : class,IShardingTable + public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext, out ICollection tail)where TEntity : class,IShardingTable { return TryGetAssertTail(shardingRouteContext,typeof(TEntity), out tail); } - public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection tail) + public static bool TryGetAssertTail(this ShardingRouteContext shardingRouteContext,Type entityType, out ICollection 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; } diff --git a/src/ShardingCore/Extensions/StreamMergeContextExtension.cs b/src/ShardingCore/Extensions/StreamMergeContextExtension.cs index a78361ba..ece99fc2 100644 --- a/src/ShardingCore/Extensions/StreamMergeContextExtension.cs +++ b/src/ShardingCore/Extensions/StreamMergeContextExtension.cs @@ -19,19 +19,45 @@ namespace ShardingCore.Extensions /// /// /// - public static bool IsShardingQuery(this StreamMergeContext streamMergeContext) + public static bool IsNormalQuery(this StreamMergeContext streamMergeContext) { - return streamMergeContext.TableRouteResults.Count() > 1; + return streamMergeContext.QueryEntities.Any(o=>!o.IsShardingDataSource()&&!o.IsShardingTable()); } + /// + /// 单路由查询 + /// + /// + /// + /// + public static bool IsSingleRouteQuery(this StreamMergeContext streamMergeContext) + { + return streamMergeContext.DataSourceRouteResult.IntersectDataSources.Count==1&&streamMergeContext.TableRouteResults.Count()==1; + } + /// + /// 单表查询 + /// + /// + /// + /// public static bool IsSingleShardingTableQuery(this StreamMergeContext streamMergeContext) { return streamMergeContext.TableRouteResults.First().ReplaceTables.Count(o => o.EntityType.IsShardingTable()) == 1; } - - public static IVirtualTableManager GetVirtualTableManager(this StreamMergeContext streamMergeContext) + /// + /// 本次查询仅包含一个对象的分表分库 + /// + /// + /// + /// + public static bool IsSingleShardingQuery(this StreamMergeContext 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(this StreamMergeContext streamMergeContext) + { + var queryEntities = streamMergeContext.GetOriginalQueryable().ParseQueryableRoute(); + //仅一个对象支持分库或者分表的组合 + return queryEntities.Count(o=>(o.IsShardingDataSource()&&!o.IsShardingTable()) ||(o.IsShardingDataSource()&& o.IsShardingTable())|| (!o.IsShardingDataSource() && o.IsShardingTable())) ==1; } } } \ No newline at end of file diff --git a/src/ShardingCore/Sharding/PaginationConfigurations/IPaginationConfiguration.cs b/src/ShardingCore/Sharding/PaginationConfigurations/IPaginationConfiguration.cs index 44f6f56a..4eebc9e0 100644 --- a/src/ShardingCore/Sharding/PaginationConfigurations/IPaginationConfiguration.cs +++ b/src/ShardingCore/Sharding/PaginationConfigurations/IPaginationConfiguration.cs @@ -12,7 +12,7 @@ namespace ShardingCore.Sharding.PaginationConfigurations * @Ver: 1.0 * @Email: 326308290@qq.com */ - public interface IPaginationConfiguration where TEntity : class,IShardingTable + public interface IPaginationConfiguration where TEntity : class { void Configure(PaginationBuilder builder); } diff --git a/src/ShardingCore/Sharding/PaginationConfigurations/PaginationOrderPropertyBuilder.cs b/src/ShardingCore/Sharding/PaginationConfigurations/PaginationOrderPropertyBuilder.cs index 26668fc8..a3d64b67 100644 --- a/src/ShardingCore/Sharding/PaginationConfigurations/PaginationOrderPropertyBuilder.cs +++ b/src/ShardingCore/Sharding/PaginationConfigurations/PaginationOrderPropertyBuilder.cs @@ -23,12 +23,12 @@ namespace ShardingCore.Sharding.PaginationConfigurations /// /// 使用哪个后缀比较 /// - /// + /// /// - public PaginationOrderPropertyBuilder UseTailComparer(IComparer tailComparer) + public PaginationOrderPropertyBuilder UseRouteComparer(IComparer routeComparer) { - _paginationSequenceConfig.TailComparer= tailComparer ?? throw new ArgumentException(nameof(tailComparer)); + _paginationSequenceConfig.RouteComparer= routeComparer ?? throw new ArgumentException(nameof(routeComparer)); return this; } /// @@ -45,10 +45,12 @@ namespace ShardingCore.Sharding.PaginationConfigurations /// 如果查询没发现排序就将当前配置追加上去 /// /// 大于等于0生效,越大优先级越高 + /// 默认asc还是desc /// - public PaginationOrderPropertyBuilder UseAppendIfOrderNone(int order=0) + public PaginationOrderPropertyBuilder UseAppendIfOrderNone(int order=0,bool defAsc=true) { _paginationSequenceConfig.AppendOrder = order; + _paginationSequenceConfig.AppendAsc = defAsc; return this; } } diff --git a/src/ShardingCore/Sharding/PaginationConfigurations/PaginationSequenceConfig.cs b/src/ShardingCore/Sharding/PaginationConfigurations/PaginationSequenceConfig.cs index 5217de10..bc36fe63 100644 --- a/src/ShardingCore/Sharding/PaginationConfigurations/PaginationSequenceConfig.cs +++ b/src/ShardingCore/Sharding/PaginationConfigurations/PaginationSequenceConfig.cs @@ -17,16 +17,16 @@ namespace ShardingCore.Sharding.PaginationConfigurations */ public class PaginationSequenceConfig { - public PaginationSequenceConfig(LambdaExpression orderPropertyExpression, PaginationMatchEnum paginationMatchEnum= PaginationMatchEnum.Owner, IComparer tailComparer=null) + public PaginationSequenceConfig(LambdaExpression orderPropertyExpression, PaginationMatchEnum paginationMatchEnum= PaginationMatchEnum.Owner, IComparer routeComparer=null) { OrderPropertyInfo = orderPropertyExpression.GetPropertyAccess(); PropertyName = OrderPropertyInfo.Name; PaginationMatchEnum = paginationMatchEnum; - TailComparer = tailComparer ?? Comparer.Default; + RouteComparer = routeComparer ?? Comparer.Default; SequenceTails = new HashSet(); } - public IComparer TailComparer { get; set; } + public IComparer RouteComparer { get; set; } public PaginationMatchEnum PaginationMatchEnum { get; set; } public PropertyInfo OrderPropertyInfo { get; set; } @@ -38,6 +38,8 @@ namespace ShardingCore.Sharding.PaginationConfigurations /// 大于等于0表示需要 /// public int AppendOrder { get; set; } = -1; + + public bool AppendAsc { get; set; } = true; public string PropertyName { get;} public ISet SequenceTails { get; } diff --git a/src/ShardingCore/Sharding/ShardingQueryExecutors/DefaultShardingQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingQueryExecutors/DefaultShardingQueryExecutor.cs index 2cc9b4ba..b69d5159 100644 --- a/src/ShardingCore/Sharding/ShardingQueryExecutors/DefaultShardingQueryExecutor.cs +++ b/src/ShardingCore/Sharding/ShardingQueryExecutors/DefaultShardingQueryExecutor.cs @@ -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); } diff --git a/src/ShardingCore/Sharding/ShardingQueryExecutors/EnumeratorShardingQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingQueryExecutors/EnumeratorShardingQueryExecutor.cs index 9352b7b7..491ad970 100644 --- a/src/ShardingCore/Sharding/ShardingQueryExecutors/EnumeratorShardingQueryExecutor.cs +++ b/src/ShardingCore/Sharding/ShardingQueryExecutors/EnumeratorShardingQueryExecutor.cs @@ -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,89 +30,192 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors * @Ver: 1.0 * @Email: 326308290@qq.com */ - public class EnumeratorShardingQueryExecutor + public class EnumeratorShardingQueryExecutor + where TShardingDbContext : DbContext, IShardingDbContext { private readonly StreamMergeContext _streamMergeContext; private readonly IShardingPageManager _shardingPageManager; - private readonly IVirtualTableManager _virtualTableManager; - + private readonly IVirtualTableManager _virtualTableManager; + private readonly IVirtualDataSource _virtualDataSource; public EnumeratorShardingQueryExecutor(StreamMergeContext streamMergeContext) { _streamMergeContext = streamMergeContext; _shardingPageManager = ShardingContainer.GetService(); - _virtualTableManager = streamMergeContext.GetVirtualTableManager(); + _virtualTableManager = ShardingContainer.GetService>(); + _virtualDataSource = ShardingContainer.GetService>(); } public IEnumeratorStreamMergeEngine ExecuteAsync(CancellationToken cancellationToken = new CancellationToken()) { - //操作单表 - if (!_streamMergeContext.IsShardingQuery()) + //操作单表或者单分库分表之类的 + if (_streamMergeContext.IsNormalQuery()||_streamMergeContext.IsSingleRouteQuery()) { - return new SingleQueryEnumeratorAsyncStreamMergeEngine(_streamMergeContext); + return new SingleQueryEnumeratorAsyncStreamMergeEngine(_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 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 paginationMetadata = virtualTable.PaginationMetadata; - //判断本次查询的排序是否包含order,如果不包含就获取默认添加的排序 - 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(_streamMergeContext, appendPaginationConfig, _shardingPageManager.Current.RouteQueryResults); - } - } - 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(_streamMergeContext, sequenceFullMatchOrderConfig, _shardingPageManager.Current.RouteQueryResults, primaryOrder.IsAsc); - } - } + //自动添加属性顺序排序 + //除了判断属性名还要判断所属关系 + var mergeEngine = DoNoOrderAppendEnumeratorStreamMergeEngine(shardingEntityType); + if (mergeEngine != null) + return mergeEngine; + } + else + { + 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(_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( _streamMergeContext, total); - } - } - //if (paginationMetadata.EnableUnevenShardingPage) - //{ - // if (paginationMetadata.IsUseUneven(_shardingPageManager.Current.RouteQueryResults, _streamMergeContext.Skip.GetValueOrDefault())) - // { + //if (paginationMetadata.EnableUnevenShardingPage) + //{ + // if (paginationMetadata.IsUseUneven(_shardingPageManager.Current.RouteQueryResults, _streamMergeContext.Skip.GetValueOrDefault())) + // { - // } - //} - } + // } + //} } } - return new DefaultShardingEnumeratorAsyncStreamMergeEngine(_streamMergeContext); + return new DefaultShardingEnumeratorAsyncStreamMergeEngine(_streamMergeContext); + } + + private IEnumeratorStreamMergeEngine 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(_streamMergeContext, dataSourceSequenceOrderConfig, tableSequenceOrderConfig, _shardingPageManager.Current.RouteQueryResults); + } + + return null; + } + + private IEnumeratorStreamMergeEngine 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(_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); + } + + + //skip过大reserve skip + if (dataSourceUseReverse && tableUseReverse) + { + return new ReverseShardingEnumeratorAsyncStreamMergeEngine(_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 paginationSequenceConfigs, PropertyOrder primaryOrder) + { + return paginationSequenceConfigs.Where(o => !o.PaginationMatchEnum.HasFlag(PaginationMatchEnum.PrimaryMatch)).FirstOrDefault(o => PaginationPrimaryMatch(o, primaryOrder)); + } + private PaginationSequenceConfig GetPaginationPrimaryMatch(ISet paginationSequenceConfigs, PropertyOrder primaryOrder) + { + return paginationSequenceConfigs.Where(o => o.PaginationMatchEnum.HasFlag(PaginationMatchEnum.PrimaryMatch)).FirstOrDefault(o => PaginationPrimaryMatch(o, primaryOrder)); } private bool PaginationMatch(PaginationSequenceConfig paginationSequenceConfig) diff --git a/src/ShardingCore/Sharding/StreamMergeContext.cs b/src/ShardingCore/Sharding/StreamMergeContext.cs index 441d2667..f064f99b 100644 --- a/src/ShardingCore/Sharding/StreamMergeContext.cs +++ b/src/ShardingCore/Sharding/StreamMergeContext.cs @@ -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 TableRouteResults { get; } public DataSourceRouteResult DataSourceRouteResult { get; } + /// + /// βѯ漰Ķ + /// + public ISet QueryEntities { get; } public StreamMergeContext(IQueryable 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); diff --git a/src/ShardingCore/Sharding/StreamMergeEngines/AsyncEnumerableStreamMergeEngine.cs b/src/ShardingCore/Sharding/StreamMergeEngines/AsyncEnumerableStreamMergeEngine.cs index e9363f65..a0674dc5 100644 --- a/src/ShardingCore/Sharding/StreamMergeEngines/AsyncEnumerableStreamMergeEngine.cs +++ b/src/ShardingCore/Sharding/StreamMergeEngines/AsyncEnumerableStreamMergeEngine.cs @@ -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 : IAsyncEnumerable, IEnumerable + public class AsyncEnumerableStreamMergeEngine : IAsyncEnumerable, IEnumerable + where TShardingDbContext:DbContext,IShardingDbContext { private readonly StreamMergeContext _mergeContext; @@ -24,7 +27,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines #if !EFCORE2 public IAsyncEnumerator GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken()) { - return new EnumeratorShardingQueryExecutor(_mergeContext).ExecuteAsync(cancellationToken) + return new EnumeratorShardingQueryExecutor(_mergeContext).ExecuteAsync(cancellationToken) .GetAsyncEnumerator(cancellationToken); } #endif @@ -32,7 +35,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines #if EFCORE2 IAsyncEnumerator IAsyncEnumerable.GetEnumerator() { - return ((IAsyncEnumerable)new EnumeratorShardingQueryExecutor(_mergeContext).ExecuteAsync()) + return ((IAsyncEnumerable)new EnumeratorShardingQueryExecutor(_mergeContext).ExecuteAsync()) .GetEnumerator(); } #endif @@ -41,7 +44,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines public IEnumerator GetEnumerator() { - return ((IEnumerable)new EnumeratorShardingQueryExecutor(_mergeContext).ExecuteAsync()) + return ((IEnumerable)new EnumeratorShardingQueryExecutor(_mergeContext).ExecuteAsync()) .GetEnumerator(); } diff --git a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/AppenOrderSequenceEnumeratorAsyncStreamMergeEngine.cs b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/AppenOrderSequenceEnumeratorAsyncStreamMergeEngine.cs index 8e98c9d6..70d2c381 100644 --- a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/AppenOrderSequenceEnumeratorAsyncStreamMergeEngine.cs +++ b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/AppenOrderSequenceEnumeratorAsyncStreamMergeEngine.cs @@ -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 : AbstractEnumeratorAsyncStreamMergeEngine + public class AppenOrderSequenceEnumeratorAsyncStreamMergeEngine : AbstractEnumeratorAsyncStreamMergeEngine + where TShardingDbContext : DbContext, IShardingDbContext { - private readonly PaginationSequenceConfig _appendPaginationSequenceConfig; + private readonly PaginationSequenceConfig _dataSourceSequenceOrderConfig; + private readonly PaginationSequenceConfig _tableSequenceOrderConfig; private readonly ICollection> _routeQueryResults; - public AppenOrderSequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext streamMergeContext, PaginationSequenceConfig appendPaginationSequenceConfig, ICollection> routeQueryResults) : base(streamMergeContext) + public AppenOrderSequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext streamMergeContext, PaginationSequenceConfig dataSourceSequenceOrderConfig, PaginationSequenceConfig tableSequenceOrderConfig, ICollection> 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(); + 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 CreateAsyncExecuteQueryable(string dsname,IQueryable noPaginationQueryable, SequenceResult sequenceResult) + private IQueryable CreateAsyncExecuteQueryable(string dsname,IQueryable noPaginationQueryable, SequenceResult sequenceResult,IEnumerable reSetOrders) { var shardingDbContext = StreamMergeContext.CreateDbContext(dsname,sequenceResult.TableRouteResult); DbContextQueryStore.TryAdd(sequenceResult.TableRouteResult, shardingDbContext); - var newQueryable = (IQueryable)(noPaginationQueryable.Skip(sequenceResult.Skip).Take(sequenceResult.Take).OrderWithExpression(new PropertyOrder[]{new PropertyOrder(_appendPaginationSequenceConfig.PropertyName,true)})) + var newQueryable = (IQueryable)(noPaginationQueryable.Skip(sequenceResult.Skip).Take(sequenceResult.Take).OrderWithExpression(reSetOrders)) .ReplaceDbContextQueryable(shardingDbContext); return newQueryable; } diff --git a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/DefaultShardingEnumeratorAsyncStreamMergeEngine.cs b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/DefaultShardingEnumeratorAsyncStreamMergeEngine.cs index d778d083..d7e8e78b 100644 --- a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/DefaultShardingEnumeratorAsyncStreamMergeEngine.cs +++ b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/DefaultShardingEnumeratorAsyncStreamMergeEngine.cs @@ -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:AbstractEnumeratorAsyncStreamMergeEngine + public class DefaultShardingEnumeratorAsyncStreamMergeEngine :AbstractEnumeratorAsyncStreamMergeEngine + where TShardingDbContext : DbContext, IShardingDbContext { public DefaultShardingEnumeratorAsyncStreamMergeEngine(StreamMergeContext streamMergeContext) : base(streamMergeContext) { diff --git a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/ReverseShardingEnumeratorAsyncStreamMergeEngine.cs b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/ReverseShardingEnumeratorAsyncStreamMergeEngine.cs index 91cac6ea..66225f90 100644 --- a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/ReverseShardingEnumeratorAsyncStreamMergeEngine.cs +++ b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/ReverseShardingEnumeratorAsyncStreamMergeEngine.cs @@ -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; diff --git a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SequenceEnumeratorAsyncStreamMergeEngine.cs b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SequenceEnumeratorAsyncStreamMergeEngine.cs index 1b10e903..85aea6a9 100644 --- a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SequenceEnumeratorAsyncStreamMergeEngine.cs +++ b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SequenceEnumeratorAsyncStreamMergeEngine.cs @@ -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 : AbstractEnumeratorAsyncStreamMergeEngine + public class SequenceEnumeratorAsyncStreamMergeEngine : AbstractEnumeratorAsyncStreamMergeEngine + where TShardingDbContext : DbContext, IShardingDbContext { - private readonly PaginationSequenceConfig _orderPaginationSequenceConfig; + private readonly PaginationSequenceConfig _dataSourceSequenceMatchOrderConfig; + private readonly PaginationSequenceConfig _tableSequenceMatchOrderConfig; private readonly ICollection> _routeQueryResults; private readonly bool _isAsc; - public SequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext streamMergeContext, PaginationSequenceConfig orderPaginationSequenceConfig, ICollection> routeQueryResults, bool isAsc) : base(streamMergeContext) + public SequenceEnumeratorAsyncStreamMergeEngine(StreamMergeContext streamMergeContext, PaginationSequenceConfig dataSourceSequenceMatchOrderConfig, PaginationSequenceConfig tableSequenceMatchOrderConfig, ICollection> 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(); diff --git a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SingleQueryEnumeratorAsyncStreamMergeEngine.cs b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SingleQueryEnumeratorAsyncStreamMergeEngine.cs index 79718058..f72b7da2 100644 --- a/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SingleQueryEnumeratorAsyncStreamMergeEngine.cs +++ b/src/ShardingCore/Sharding/StreamMergeEngines/EnumeratorStreamMergeEngines/EnumeratorAsync/SingleQueryEnumeratorAsyncStreamMergeEngine.cs @@ -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 : AbstractEnumeratorAsyncStreamMergeEngine + public class SingleQueryEnumeratorAsyncStreamMergeEngine : AbstractEnumeratorAsyncStreamMergeEngine + where TShardingDbContext : DbContext, IShardingDbContext { public SingleQueryEnumeratorAsyncStreamMergeEngine(StreamMergeContext streamMergeContext) : base(streamMergeContext) { @@ -41,7 +44,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines. public override IStreamMergeAsyncEnumerator GetStreamMergeAsyncEnumerator(IStreamMergeAsyncEnumerator[] streamsAsyncEnumerators) { if (streamsAsyncEnumerators.Length != 1) - throw new ShardingCoreException($"{nameof(SingleQueryEnumeratorAsyncStreamMergeEngine)} has more {nameof(IStreamMergeAsyncEnumerator)}"); + throw new ShardingCoreException($"{nameof(SingleQueryEnumeratorAsyncStreamMergeEngine)} has more {nameof(IStreamMergeAsyncEnumerator)}"); return streamsAsyncEnumerators[0]; } } diff --git a/src/ShardingCore/ShardingDbContextBootstrapper.cs b/src/ShardingCore/ShardingDbContextBootstrapper.cs index 8f8e1353..b6a9700c 100644 --- a/src/ShardingCore/ShardingDbContextBootstrapper.cs +++ b/src/ShardingCore/ShardingDbContextBootstrapper.cs @@ -77,6 +77,7 @@ namespace ShardingCore { var routeType = _shardingConfigOption.GetVirtualDataSourceRouteType(entityType); var virtualRoute = CreateVirtualDataSourceRoute(routeType); + virtualRoute.Init(); virtualDataSource.AddVirtualDataSourceRoute(virtualRoute); } if (entityType.IsShardingTable()) diff --git a/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyDateTimeVirtualTableRoute.cs index 2dd28552..b6ffc3a9 100644 --- a/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyDateTimeVirtualTableRoute.cs @@ -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: -* @Date: Wednesday, 27 January 2021 12:29:19 -* @Email: 326308290@qq.com -*/ - public abstract class AbstractShardingTimeKeyDateTimeVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute where T:class,IShardingTable + /* + * @Author: xjm + * @Description:sharding table route by date time + * @Date: Wednesday, 27 January 2021 12:29:19 + * @Email: 326308290@qq.com + */ + /// + /// time type is date time + /// + /// + public abstract class AbstractShardingTimeKeyDateTimeVirtualTableRoute : AbstractShardingOperatorVirtualTableRoute where T : class, IShardingTable { + /// + /// how convert object to date time + /// + /// + /// protected override DateTime ConvertToShardingKey(object shardingKey) { return Convert.ToDateTime(shardingKey); } - + /// + /// how convert sharding key to tail + /// + /// + /// public override string ShardingKeyToTail(object shardingKey) { var time = ConvertToShardingKey(shardingKey); return TimeFormatToTail(time); } - + /// + /// how format date time to tail + /// + /// + /// protected abstract string TimeFormatToTail(DateTime time); } diff --git a/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyLongVirtualTableRoute.cs index 3a66115e..65a7b9b6 100644 --- a/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Abstractions/AbstractShardingTimeKeyLongVirtualTableRoute.cs @@ -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 */ + /// + /// sharding table route by time stamp (ms) + /// + /// entity public abstract class AbstractShardingTimeKeyLongVirtualTableRoute : AbstractShardingOperatorVirtualTableRoute where T : class, IShardingTable { + /// + /// how convert object to long + /// + /// + /// protected override long ConvertToShardingKey(object shardingKey) { return (long)shardingKey; } - + /// + /// how convert sharding key to tail + /// + /// + /// public override string ShardingKeyToTail(object shardingKey) { var time = ConvertToShardingKey(shardingKey); return TimeFormatToTail(time); } + /// + /// how format long time to tail + /// + /// + /// protected abstract string TimeFormatToTail(long time); } diff --git a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs index e9b64b9a..e9e37f28 100644 --- a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute.cs @@ -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:AbstractShardingTimeKeyDateTimeVirtualTableRoute where T:class,IShardingTable { + /// + /// begin time use fixed time eg.new DateTime(20xx,xx,xx) + /// + /// public abstract DateTime GetBeginTime(); + /// + /// return all tails in database + /// + /// public override List 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) { diff --git a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs index 5ddae342..d8295875 100644 --- a/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Days/AbstractSimpleShardingDayKeyLongVirtualTableRoute.cs @@ -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) { diff --git a/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyIntVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyIntVirtualTableRoute.cs index 061a56d4..77ea80c0 100644 --- a/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyIntVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyIntVirtualTableRoute.cs @@ -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 @@ -19,7 +18,7 @@ namespace ShardingCore.VirtualRoutes.Mods /// 分表字段为int的取模分表 /// /// - public abstract class AbstractSimpleShardingModKeyIntVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute where T:class,IShardingTable + public abstract class AbstractSimpleShardingModKeyIntVirtualTableRoute: AbstractShardingOperatorVirtualTableRoute where T:class,IShardingTable { protected readonly int Mod; protected readonly int TailLength; diff --git a/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs index 1285c8d5..1a8798a0 100644 --- a/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Mods/AbstractSimpleShardingModKeyStringVirtualTableRoute.cs @@ -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; @@ -20,7 +19,7 @@ namespace ShardingCore.VirtualRoutes.Mods /// 分表字段为string的取模分表 /// /// - public abstract class AbstractSimpleShardingModKeyStringVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute where T:class,IShardingTable + public abstract class AbstractSimpleShardingModKeyStringVirtualTableRoute: AbstractShardingOperatorVirtualTableRoute where T:class,IShardingTable { protected readonly int Mod; protected readonly int TailLength; diff --git a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs index 463202d2..d6bd1eb8 100644 --- a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute.cs @@ -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) { diff --git a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs index 07d035e4..7e8db45f 100644 --- a/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Months/AbstractSimpleShardingMonthKeyLongVirtualTableRoute.cs @@ -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) { diff --git a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs index 40bf54c1..fa46bbfe 100644 --- a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute.cs @@ -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) { diff --git a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs index 79cc8f65..35381fdc 100644 --- a/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Weeks/AbstractSimpleShardingWeekKeyLongVirtualTableRoute.cs @@ -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) { diff --git a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs index 01c0652d..99f351ca 100644 --- a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute.cs @@ -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) { diff --git a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs index e1ebb6b8..dadff271 100644 --- a/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs +++ b/src/ShardingCore/VirtualRoutes/Years/AbstractSimpleShardingYearKeyLongVirtualTableRoute.cs @@ -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) { diff --git a/test/ShardingCore.Test50/ShardingTest.cs b/test/ShardingCore.Test50/ShardingTest.cs index 78ee45e6..b007058c 100644 --- a/test/ShardingCore.Test50/ShardingTest.cs +++ b/test/ShardingCore.Test50/ShardingTest.cs @@ -52,7 +52,7 @@ namespace ShardingCore.Test50 { using (_shardingRouteManager.CreateScope()) { - _shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); + _shardingRouteManager.Current.MustTable.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); var mod00s = await _virtualDbContext.Set().ToListAsync(); Assert.Equal(333, mod00s.Count); diff --git a/test/ShardingCore.Test50/Shardings/SysUserModVirtualTableRoute.cs b/test/ShardingCore.Test50/Shardings/SysUserModVirtualTableRoute.cs index 8bfd0ae2..8437a5f4 100644 --- a/test/ShardingCore.Test50/Shardings/SysUserModVirtualTableRoute.cs +++ b/test/ShardingCore.Test50/Shardings/SysUserModVirtualTableRoute.cs @@ -1,19 +1,14 @@ -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 { -/* -* @Author: xjm -* @Description: -* @Date: Thursday, 14 January 2021 15:39:27 -* @Email: 326308290@qq.com -*/ + /* + * @Author: xjm + * @Description: + * @Date: Thursday, 14 January 2021 15:39:27 + * @Email: 326308290@qq.com + */ public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute { protected override bool EnableHintRoute => true; diff --git a/test/ShardingCore.Test50_2x/ShardingTest.cs b/test/ShardingCore.Test50_2x/ShardingTest.cs index 01bbbce7..c5338782 100644 --- a/test/ShardingCore.Test50_2x/ShardingTest.cs +++ b/test/ShardingCore.Test50_2x/ShardingTest.cs @@ -48,7 +48,7 @@ namespace ShardingCore.Test50_2x { using (_shardingRouteManager.CreateScope()) { - _shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); + _shardingRouteManager.Current.MustTable.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); var mod00s = await _virtualDbContext.Set().ToListAsync(); Assert.Equal(333, mod00s.Count); diff --git a/test/ShardingCore.Test50_3x/ShardingTest.cs b/test/ShardingCore.Test50_3x/ShardingTest.cs index 875deb35..1daf9743 100644 --- a/test/ShardingCore.Test50_3x/ShardingTest.cs +++ b/test/ShardingCore.Test50_3x/ShardingTest.cs @@ -48,7 +48,7 @@ namespace ShardingCore.Test50_3x { using (_shardingRouteManager.CreateScope()) { - _shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); + _shardingRouteManager.Current.MustTable.TryAdd(typeof(SysUserMod), new HashSet() { "00" }); var mod00s = await _virtualDbContext.Set().ToListAsync(); Assert.Equal(333, mod00s.Count);