修复未读写分离时候的bug(读取了读写分离配置并且使用了),并且添加了路由解析编译缓存可选项,并且发布x.3.1.61

This commit is contained in:
xuejiaming 2021-12-02 13:52:38 +08:00
parent 0e1e2d8157
commit c23d72bca3
61 changed files with 298 additions and 123 deletions

View File

@ -118,18 +118,16 @@ namespace ShardingCore6x
public int N;
//[Benchmark]
//public async Task NoShardingFirstOrDefaultAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
// var queryable1 = _defaultShardingDbContext.Set<Order>().Where(o => next== o.Id);
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable1));
// }
//}
[Benchmark]
public async Task NoRouteParseCache()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 3000000).ToString();
var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
_virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
}
}
//[Benchmark]
//public async Task ShardingFirstOrDefaultAsync()

View File

@ -1,9 +1,9 @@
:start
::定义版本
set EFCORE2=2.3.1.60
set EFCORE3=3.3.1.60
set EFCORE5=5.3.1.60
set EFCORE6=6.3.1.60
set EFCORE2=2.3.1.61
set EFCORE3=3.3.1.61
set EFCORE5=5.3.1.61
set EFCORE6=6.3.1.61
::删除所有bin与obj下的文件
@echo off

View File

@ -20,9 +20,9 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
/// <summary>
/// 过滤虚拟路由用于处理强制路由、提示路由、路由断言
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class AbstractShardingFilterVirtualDataSourceRoute<T, TKey> : AbstractVirtualDataSourceRoute<T, TKey> where T : class
public abstract class AbstractShardingFilterVirtualDataSourceRoute<TEntity, TKey> : AbstractVirtualDataSourceRoute<TEntity, TKey> where TEntity : class
{
public ShardingRouteContext CurrentShardingRouteContext =>
@ -35,7 +35,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
/// 启用断言路由
/// </summary>
protected virtual bool EnableAssertRoute => false;
public override List<string> RouteWithPredicate(IQueryable queryable,bool isQuery)
public override List<string> RouteWithPredicate(IQueryable queryable, bool isQuery)
{
var allDataSourceNames = GetAllDataSourceNames();
if (!isQuery)
@ -48,44 +48,55 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
{
if (CurrentShardingRouteContext != null)
{
if (CurrentShardingRouteContext.TryGetMustDataSource<T>(out HashSet<string> mustDataSources) && mustDataSources.IsNotEmpty())
if (CurrentShardingRouteContext.TryGetMustDataSource<TEntity>(out HashSet<string> mustDataSources) && mustDataSources.IsNotEmpty())
{
var dataSources = allDataSourceNames.Where(o => mustDataSources.Contains(o)).ToList();
if (dataSources.IsEmpty()||dataSources.Count!=mustDataSources.Count)
if (dataSources.IsEmpty() || dataSources.Count != mustDataSources.Count)
throw new ShardingCoreException(
$" sharding data source route must error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",mustDataSources)}]");
$" sharding data source route must error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",", mustDataSources)}]");
return dataSources;
}
if (CurrentShardingRouteContext.TryGetHintDataSource<T>(out HashSet<string> hintDataSources) && hintDataSources.IsNotEmpty())
if (CurrentShardingRouteContext.TryGetHintDataSource<TEntity>(out HashSet<string> hintDataSources) && hintDataSources.IsNotEmpty())
{
var dataSources = allDataSourceNames.Where(o => hintDataSources.Contains(o)).ToList();
if (dataSources.IsEmpty()||dataSources.Count!=hintDataSources.Count)
if (dataSources.IsEmpty() || dataSources.Count != hintDataSources.Count)
throw new ShardingCoreException(
$" sharding data source route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",hintDataSources)}]");
$" sharding data source route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",", hintDataSources)}]");
return GetFilterDataSourceNames(allDataSourceNames, dataSources);
}
}
}
var filterDataSources = DoRouteWithPredicate(allDataSourceNames, queryable);
return GetFilterDataSourceNames(allDataSourceNames,filterDataSources);
return GetFilterDataSourceNames(allDataSourceNames, filterDataSources);
}
/// <summary>
/// 判断是调用全局还是内部断言
/// </summary>
/// <param name="allDataSourceNames"></param>
/// <param name="filterDataSources"></param>
/// <returns></returns>
private List<string> GetFilterDataSourceNames(List<string> allDataSourceNames, List<string> filterDataSources)
{
//后拦截器
var resultDataSources = AfterDataSourceFilter(allDataSourceNames, filterDataSources);
if (UseAssertRoute)
{
//最后处理断言
ProcessAssertRoutes(allDataSourceNames, resultDataSources);
return resultDataSources;
ProcessAssertRoutes(allDataSourceNames, filterDataSources);
return filterDataSources;
}
else
{
return AfterDataSourceFilter(allDataSourceNames, filterDataSources);
}
}
private bool UseAssertRoute => EnableAssertRoute && CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertDataSource<TEntity>(out ICollection<IDataSourceRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty();
private void ProcessAssertRoutes(List<string> allDataSources,List<string> filterDataSources)
private void ProcessAssertRoutes(List<string> allDataSources, List<string> filterDataSources)
{
if (EnableAssertRoute)
{
if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertDataSource<T>(out ICollection<IDataSourceRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty())
if (CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetAssertDataSource<TEntity>(out ICollection<IDataSourceRouteAssert> routeAsserts) && routeAsserts.IsNotEmpty())
{
foreach (var routeAssert in routeAsserts)
{

View File

@ -20,14 +20,17 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
/// <summary>
/// 抽象类型抽象出对应的条件表达式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class AbstractShardingOperatorVirtualDataSourceRoute<T, TKey> : AbstractShardingFilterVirtualDataSourceRoute<T, TKey> where T : class
public abstract class AbstractShardingOperatorVirtualDataSourceRoute<TEntity, TKey> : AbstractShardingRouteParseCompileCacheVirtualDataSourceRoute<TEntity, TKey> where TEntity : class
{
protected override List<string> DoRouteWithPredicate(List<string> allDataSourceNames, IQueryable queryable)
{
//获取所有需要路由的表后缀
var filter = ShardingUtil.GetRouteShardingTableFilter<TKey>(queryable, EntityMetadata, GetRouteToFilter,false);
//获取路由后缀表达式
var routeParseExpression = ShardingUtil.GetRouteParseExpression<TKey>(queryable, EntityMetadata, GetRouteToFilter, false);
//表达式缓存编译
var filter = CachingCompile(routeParseExpression);
//通过编译结果进行过滤
var dataSources = allDataSourceNames.Where(o => filter(o)).ToList();
return dataSources;
}

View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Visitors;
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
{
/// <summary>
/// 分库路由表达式解析缓存
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class AbstractShardingRouteParseCompileCacheVirtualDataSourceRoute<TEntity, TKey> : AbstractShardingFilterVirtualDataSourceRoute<TEntity, TKey> where TEntity : class
{
private static readonly ConcurrentDictionary<Expression<Func<string, bool>>, Func<string, bool>> _routeCompileCaches = new(new ExtensionExpressionComparer.ExpressionEqualityComparer());
static AbstractShardingRouteParseCompileCacheVirtualDataSourceRoute()
{
Expression<Func<string, bool>> defaultWhere1 = x => true;
_routeCompileCaches.TryAdd(defaultWhere1, defaultWhere1.Compile());
Expression<Func<string, bool>> defaultWhere2 = x => true;
var expression = defaultWhere2.And(defaultWhere1);
_routeCompileCaches.TryAdd(expression, expression.Compile());
}
/// <summary>
/// 是否启用路由解析编译缓存
/// </summary>
public virtual bool EnableRouteParseCompileCache => false;
/// <summary>
/// 对表达式进行缓存编译默认永久缓存单个参数表达式且不包含orElse只包含单个AndAlso或者没有AndAlso的,
/// 比如:<![CDATA[o.id==x]]>或者<![CDATA[o.id>x]]>,不会缓存<![CDATA[o=>id>x && o.id<y ]]>等一共大于、等于、小于、大于等于、小于等于(不等于编译成<![CDATA[t=>true]]>)缓存会存在的数量个数上限为
/// 表后缀x*5+2当前表如果有300个后缀那么就是1502个缓存结果额外两个为<![CDATA[o=>true]]>和<![CDATA[o=>true and true]]>
/// </summary>
/// <param name="parseWhere"></param>
/// <returns></returns>
public virtual Func<string, bool> CachingCompile(Expression<Func<string, bool>> parseWhere)
{
if (EnableRouteParseCompileCache)
{
var doCachingCompile = DoCachingCompile(parseWhere);
if (doCachingCompile != null)
return doCachingCompile;
doCachingCompile = CustomerCachingCompile(parseWhere);
if (doCachingCompile != null)
return doCachingCompile;
}
return parseWhere.Compile();
}
/// <summary>
/// 系统默认永久单表达式缓存
/// </summary>
/// <param name="parseWhere"></param>
/// <returns>返回null会走<see cref="CustomerCachingCompile"/>这个方法如果还是null就会调用<see cref="Compile"/>方法</returns>
protected virtual Func<string, bool> DoCachingCompile(Expression<Func<string, bool>> parseWhere)
{
var shouldCache = ShouldCache(parseWhere);
if (shouldCache)
return _routeCompileCaches.GetOrAdd(parseWhere, key => parseWhere.Compile());
return null;
}
/// <summary>
/// 表达式是否应该被缓存默认没有or并且and只有一个或者没有
/// </summary>
/// <param name="whereExpression"></param>
/// <returns></returns>
protected bool ShouldCache(Expression whereExpression)
{
var routeParseCacheExpressionVisitor = new RouteParseCacheExpressionVisitor();
routeParseCacheExpressionVisitor.Visit(whereExpression);
if (routeParseCacheExpressionVisitor.HasOrElse())
return false;
if (routeParseCacheExpressionVisitor.AndAlsoCount() > 1)
return false;
return true;
}
protected virtual Func<string, bool> CustomerCachingCompile(Expression<Func<string, bool>> parseWhere)
{
return null;
}
}
}

View File

@ -63,22 +63,24 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
if (physicTables.IsEmpty()||physicTables.Count!=hintTails.Count)
throw new ShardingCoreException(
$" sharding route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",hintTails)}]");
if (UseAssertRoute)
{
ProcessAssertRoutes(allPhysicTables, physicTables);
return physicTables;
}
else
{
//后拦截器
return AfterPhysicTableFilter(allPhysicTables, physicTables);
}
return GetFilterTableNames(allPhysicTables, physicTables);
}
}
}
var filterPhysicTables = DoRouteWithPredicate(allPhysicTables,queryable);
return GetFilterTableNames(allPhysicTables, filterPhysicTables);
}
/// <summary>
/// 判断是调用全局过滤器还是调用内部断言
/// </summary>
/// <param name="allPhysicTables"></param>
/// <param name="filterPhysicTables"></param>
/// <returns></returns>
private List<IPhysicTable> GetFilterTableNames(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
{
if (UseAssertRoute)
{
//最后处理断言

View File

@ -16,12 +16,15 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
* @Date: Saturday, 19 December 2020 19:55:24
* @Email: 326308290@qq.com
*/
public abstract class AbstractShardingOperatorVirtualTableRoute<TEntity, TKey> : AbstractShardingFilterVirtualTableRoute<TEntity, TKey> where TEntity : class
public abstract class AbstractShardingOperatorVirtualTableRoute<TEntity, TKey> : AbstractShardingRouteParseCompileCacheVirtualTableRoute<TEntity, TKey> where TEntity : class
{
protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
{
//获取所有需要路由的表后缀
var filter = ShardingUtil.GetRouteShardingTableFilter<TKey>(queryable, EntityMetadata, GetRouteToFilter,true);
//获取路由后缀表达式
var routeParseExpression = ShardingUtil.GetRouteParseExpression<TKey>(queryable, EntityMetadata, GetRouteToFilter,true);
//表达式缓存编译
var filter=CachingCompile(routeParseExpression);
//通过编译结果进行过滤
var physicTables = allPhysicTables.Where(o => filter(o.Tail)).ToList();
return physicTables;
}

View File

@ -1,38 +1,89 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Visitors;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
{
public class AbstractShardingRouteParseCompileCacheVirtualTableRoute<TEntity, TKey> : AbstractShardingFilterVirtualTableRoute<TEntity, TKey> where TEntity : class
/// <summary>
/// 路由解析缓存
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <typeparam name="TKey"></typeparam>
public abstract class AbstractShardingRouteParseCompileCacheVirtualTableRoute<TEntity, TKey> : AbstractShardingFilterVirtualTableRoute<TEntity, TKey> where TEntity : class
{
public override string ShardingKeyToTail(object shardingKey)
private readonly ConcurrentDictionary<Expression<Func<string, bool>>, Func<string, bool>> _routeCompileCaches = new(new ExtensionExpressionComparer.ExpressionEqualityComparer());
protected AbstractShardingRouteParseCompileCacheVirtualTableRoute()
{
throw new NotImplementedException();
Expression<Func<string, bool>> defaultWhere1 = x => true;
_routeCompileCaches.TryAdd(defaultWhere1, defaultWhere1.Compile());
Expression<Func<string, bool>> defaultWhere2 = x => true;
var expression = defaultWhere2.And(defaultWhere1);
_routeCompileCaches.TryAdd(expression, expression.Compile());
}
/// <summary>
/// 是否启用路由解析编译缓存
/// </summary>
public virtual bool EnableRouteParseCompileCache => false;
/// <summary>
/// 对表达式进行缓存编译默认永久缓存单个参数表达式且不包含orElse只包含单个AndAlso或者没有AndAlso的,
/// 比如:<![CDATA[o.id==x]]>或者<![CDATA[o.id>x]]>,不会缓存<![CDATA[o=>id>x && o.id<y ]]>等一共大于、等于、小于、大于等于、小于等于(不等于编译成<![CDATA[t=>true]]>)缓存会存在的数量个数上限为
/// 表后缀x*5+2当前表如果有300个后缀那么就是1502个缓存结果额外两个为<![CDATA[o=>true]]>和<![CDATA[o=>true and true]]>
/// </summary>
/// <param name="parseWhere"></param>
/// <returns></returns>
public virtual Func<string, bool> CachingCompile(Expression<Func<string, bool>> parseWhere)
{
if (EnableRouteParseCompileCache)
{
var doCachingCompile = DoCachingCompile(parseWhere);
if (doCachingCompile != null)
return doCachingCompile;
doCachingCompile = CustomerCachingCompile(parseWhere);
if (doCachingCompile != null)
return doCachingCompile;
}
return parseWhere.Compile();
}
/// <summary>
/// 系统默认永久单表达式缓存
/// </summary>
/// <param name="parseWhere"></param>
/// <returns>返回null会走<see cref="CustomerCachingCompile"/>这个方法如果还是null就会调用<see cref="Compile"/>方法</returns>
protected virtual Func<string, bool> DoCachingCompile(Expression<Func<string, bool>> parseWhere)
{
var shouldCache = ShouldCache(parseWhere);
if(shouldCache)
return _routeCompileCaches.GetOrAdd(parseWhere, key => parseWhere.Compile());
return null;
}
/// <summary>
/// 表达式是否应该被缓存默认没有or并且and只有一个或者没有
/// </summary>
/// <param name="whereExpression"></param>
/// <returns></returns>
protected bool ShouldCache(Expression whereExpression)
{
var routeParseCacheExpressionVisitor = new RouteParseCacheExpressionVisitor();
routeParseCacheExpressionVisitor.Visit(whereExpression);
if (routeParseCacheExpressionVisitor.HasOrElse())
return false;
if (routeParseCacheExpressionVisitor.AndAlsoCount() > 1)
return false;
return true;
}
public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
protected virtual Func<string, bool> CustomerCachingCompile(Expression<Func<string, bool>> parseWhere)
{
throw new NotImplementedException();
}
public override List<string> GetAllTails()
{
throw new NotImplementedException();
}
public override void Configure(EntityMetadataTableBuilder<TEntity> builder)
{
throw new NotImplementedException();
}
protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
{
throw new NotImplementedException();
return null;
}
}
}

View File

@ -34,8 +34,11 @@ namespace ShardingCore.Sharding
_readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
_shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>();
_useReadWriteSeparation = _connectionStringManager is ReadWriteConnectionStringManager<TShardingDbContext>;
if (_readWriteOptions != null)
{
ReadWriteSeparationPriority = _readWriteOptions.ReadWritePriority;
ReadWriteSeparation = _readWriteOptions.ReadWriteSupport;
}
}
//public bool IsUseReadWriteSeparation()

View File

@ -27,17 +27,8 @@ namespace ShardingCore.Core.Internal.Visitors
public class QueryableRouteShardingTableDiscoverVisitor<TKey> : ExpressionVisitor
{
private static readonly ConcurrentDictionary<Expression<Func<string, bool>>, Func<string, bool>> _routeFilter = new(new ExtensionExpressionComparer.ExpressionEqualityComparer());
private readonly EntityMetadata _entityMetadata;
private readonly Func<TKey, ShardingOperatorEnum, Expression<Func<string, bool>>> _keyToTailWithFilter;
static QueryableRouteShardingTableDiscoverVisitor()
{
Expression<Func<string, bool>> defaultWhere1 = x => true;
_routeFilter.TryAdd(defaultWhere1, defaultWhere1.Compile());
Expression<Func<string, bool>> defaultWhere2 = x => true;
var expression = defaultWhere1.And(defaultWhere2);
_routeFilter.TryAdd(expression, expression.Compile());
}
/// <summary>
/// 是否是分表路由
/// </summary>
@ -51,42 +42,11 @@ namespace ShardingCore.Core.Internal.Visitors
_shardingTableRoute = shardingTableRoute;
}
public Func<string, bool> GetStringFilterTail()
public Expression<Func<string, bool>> GetRouteParseExpression()
{
//if (_lastExpression == null)
//{
// _lastExpression = _where;
//}
//else
//{
// var startNew = Stopwatch.StartNew();
// for (int i = 0; i < 300; i++)
// {
// var exxq = LambdaCompare.Eq(_lastExpression, _where);
// }
// startNew.Stop();
// var x = startNew.ElapsedMilliseconds;
// var eq = LambdaCompare.Eq(_lastExpression, _where);
// _lastExpression = _where;
//}
return _where.Compile();
//var shouldCache = ShouldCache(_where);
//if (shouldCache)
// return _routeFilter.GetOrAdd(_where, key => _where.Compile());
//return _where.Compile();
return _where;
}
private bool ShouldCache(Expression whereExpression)
{
var routeParseCacheExpressionVisitor = new RouteParseCacheExpressionVisitor();
routeParseCacheExpressionVisitor.Visit(whereExpression);
if (routeParseCacheExpressionVisitor.HasOrElse())
return false;
var hasAndAlsoCount = routeParseCacheExpressionVisitor.HasAndAlsoCount();
if (hasAndAlsoCount > 1)
return false;
return true;
}
private bool IsShardingKey(Expression expression)
{

View File

@ -10,7 +10,8 @@ namespace ShardingCore.Sharding.Visitors
internal class RouteParseCacheExpressionVisitor : ExpressionVisitor
{
private bool _hasOrElse = false;
private int _hasAndAlsoCount = 0;
private int _andAlsoCount = 0;
private int _equalCount = 0;
protected override Expression VisitBinary(BinaryExpression node)
{
if (node.NodeType == ExpressionType.OrElse)
@ -21,7 +22,10 @@ namespace ShardingCore.Sharding.Visitors
}
}else if (node.NodeType == ExpressionType.AndAlso)
{
_hasAndAlsoCount++;
_andAlsoCount++;
}else if (node.NodeType == ExpressionType.Equal)
{
_equalCount++;
}
return base.VisitBinary(node);
}
@ -31,9 +35,13 @@ namespace ShardingCore.Sharding.Visitors
return _hasOrElse;
}
public int HasAndAlsoCount()
public int AndAlsoCount()
{
return _hasAndAlsoCount;
return _andAlsoCount;
}
public int EqualCount()
{
return _equalCount;
}
}
}

View File

@ -52,14 +52,14 @@ namespace ShardingCore.Utils
/// <param name="keyToTailExpression"></param>
/// <param name="shardingTableRoute">sharding table or data source</param>
/// <returns></returns>
public static Func<string, bool> GetRouteShardingTableFilter<TKey>(IQueryable queryable, EntityMetadata entityMetadata, Func<TKey, ShardingOperatorEnum, Expression<Func<string, bool>>> keyToTailExpression,bool shardingTableRoute)
public static Expression<Func<string, bool>> GetRouteParseExpression<TKey>(IQueryable queryable, EntityMetadata entityMetadata, Func<TKey, ShardingOperatorEnum, Expression<Func<string, bool>>> keyToTailExpression,bool shardingTableRoute)
{
QueryableRouteShardingTableDiscoverVisitor<TKey> visitor = new QueryableRouteShardingTableDiscoverVisitor<TKey>(entityMetadata, keyToTailExpression, shardingTableRoute);
visitor.Visit(queryable.Expression);
return visitor.GetStringFilterTail();
return visitor.GetRouteParseExpression();
}
/// <summary>
/// 获取本次查询的所有涉及到的对象

View File

@ -445,6 +445,7 @@ namespace ShardingCore.Test
[Fact]
public async Task FirstOrDefault2()
{
var sysUserModabxxxxx = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth>=202102).FirstOrDefaultAsync();
var sysUserModabxxx = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_2").FirstOrDefaultAsync();
var sysUserModabxxx11 = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_2"|| o.Name == "name_3").FirstOrDefaultAsync();
var x=new Object [] { "1", "2" };

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogDayLongVirtualRoute:AbstractSimpleShardingDayKeyLongVirtualTableRoute<LogDayLong>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override void Configure(EntityMetadataTableBuilder<LogDayLong> builder)

View File

@ -10,6 +10,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogDayVirtualTableRoute:AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute<LogDay>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override DateTime GetBeginTime()

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogMonthLongvirtualRoute:AbstractSimpleShardingMonthKeyLongVirtualTableRoute<LogMonthLong>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override bool AutoCreateTableByTime()

View File

@ -7,6 +7,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogWeekDateTimeVirtualTableRoute:AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute<LogWeekDateTime>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override bool AutoCreateTableByTime()

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogWeekTimeLongVirtualTableRoute : AbstractSimpleShardingWeekKeyLongVirtualTableRoute<LogWeekTimeLong>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override bool AutoCreateTableByTime()

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogYearDateTimeVirtualRoute:AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute<LogYearDateTime>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override bool AutoCreateTableByTime()

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test.Shardings
{
public class LogYearLongVirtualRoute:AbstractSimpleShardingYearKeyLongVirtualTableRoute<LogYearLong>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute => true;
public override void Configure(EntityMetadataTableBuilder<LogYearLong> builder)

View File

@ -10,6 +10,7 @@ namespace ShardingCore.Test.Shardings
{
public class OrderAreaShardingVirtualDataSourceRoute:AbstractShardingOperatorVirtualDataSourceRoute<Order,string>
{
public override bool EnableRouteParseCompileCache => true;
protected override bool EnableHintRoute =>true;
private readonly List<string> _dataSources = new List<string>()

View File

@ -9,6 +9,7 @@ namespace ShardingCore.Test.Shardings
{
public class OrderCreateTimeVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
{
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{
return new DateTime(2021, 1, 1);

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test.Shardings
public class SysUserModIntVirtualRoute:AbstractSimpleShardingModKeyIntVirtualTableRoute<SysUserModInt>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModIntVirtualRoute() : base(2, 3)
{

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test.Shardings
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModVirtualTableRoute() : base(2,3)
{

View File

@ -16,6 +16,7 @@ namespace ShardingCore.Test.Shardings
*/
public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<SysUserSalary,int>
{
public override bool EnableRouteParseCompileCache => true;
public override string ShardingKeyToTail(object shardingKey)
{

View File

@ -10,6 +10,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogDayLongVirtualRoute:AbstractSimpleShardingDayKeyLongVirtualTableRoute<LogDayLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override void Configure(EntityMetadataTableBuilder<LogDayLong> builder)
{

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogDayVirtualTableRoute:AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute<LogDay>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogMonthLongvirtualRoute:AbstractSimpleShardingMonthKeyLongVirtualTableRoute<LogMonthLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogWeekDateTimeVirtualTableRoute:AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute<LogWeekDateTime>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogWeekTimeLongVirtualTableRoute : AbstractSimpleShardingWeekKeyLongVirtualTableRoute<LogWeekTimeLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogYearDateTimeVirtualRoute:AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute<LogYearDateTime>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test2x.Shardings
public class LogYearLongVirtualRoute:AbstractSimpleShardingYearKeyLongVirtualTableRoute<LogYearLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override void Configure(EntityMetadataTableBuilder<LogYearLong> builder)
{

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test2x.Shardings
public class OrderAreaShardingVirtualDataSourceRoute:AbstractShardingOperatorVirtualDataSourceRoute<Order,string>
{
protected override bool EnableHintRoute =>true;
public override bool EnableRouteParseCompileCache => true;
private readonly List<string> _dataSources = new List<string>()
{

View File

@ -9,6 +9,7 @@ namespace ShardingCore.Test2x.Shardings
{
public class OrderCreateTimeVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
{
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{
return new DateTime(2021, 1, 1);

View File

@ -7,6 +7,7 @@ namespace ShardingCore.Test2x.Shardings
public class SysUserModIntVirtualRoute:AbstractSimpleShardingModKeyIntVirtualTableRoute<SysUserModInt>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModIntVirtualRoute() : base(2, 3)
{

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test2x.Shardings
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModVirtualTableRoute() : base(2,3)
{

View File

@ -16,6 +16,7 @@ namespace ShardingCore.Test2x.Shardings
*/
public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<SysUserSalary,int>
{
public override bool EnableRouteParseCompileCache => true;
public override string ShardingKeyToTail(object shardingKey)
{
var time = Convert.ToInt32(shardingKey);

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogDayLongVirtualRoute:AbstractSimpleShardingDayKeyLongVirtualTableRoute<LogDayLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override void Configure(EntityMetadataTableBuilder<LogDayLong> builder)
{

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogDayVirtualTableRoute:AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute<LogDay>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogMonthLongvirtualRoute:AbstractSimpleShardingMonthKeyLongVirtualTableRoute<LogMonthLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogWeekDateTimeVirtualTableRoute:AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute<LogWeekDateTime>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogWeekTimeLongVirtualTableRoute : AbstractSimpleShardingWeekKeyLongVirtualTableRoute<LogWeekTimeLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogYearDateTimeVirtualRoute:AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute<LogYearDateTime>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test3x.Shardings
public class LogYearLongVirtualRoute:AbstractSimpleShardingYearKeyLongVirtualTableRoute<LogYearLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override void Configure(EntityMetadataTableBuilder<LogYearLong> builder)
{

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test3x.Shardings
public class OrderAreaShardingVirtualDataSourceRoute:AbstractShardingOperatorVirtualDataSourceRoute<Order,string>
{
protected override bool EnableHintRoute =>true;
public override bool EnableRouteParseCompileCache => true;
private readonly List<string> _dataSources = new List<string>()
{

View File

@ -9,6 +9,7 @@ namespace ShardingCore.Test3x.Shardings
{
public class OrderCreateTimeVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
{
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{
return new DateTime(2021, 1, 1);

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test3x.Shardings
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModIntVirtualRoute() : base(2, 3)
{
}

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test3x.Shardings
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModVirtualTableRoute() : base(2,3)
{

View File

@ -17,6 +17,7 @@ namespace ShardingCore.Test3x.Shardings
public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<SysUserSalary,int>
{
public override bool EnableRouteParseCompileCache => true;
public override string ShardingKeyToTail(object shardingKey)
{
var time = Convert.ToInt32(shardingKey);

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogDayLongVirtualRoute:AbstractSimpleShardingDayKeyLongVirtualTableRoute<LogDayLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override void Configure(EntityMetadataTableBuilder<LogDayLong> builder)
{

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogDayVirtualTableRoute:AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute<LogDay>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogMonthLongvirtualRoute:AbstractSimpleShardingMonthKeyLongVirtualTableRoute<LogMonthLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -8,6 +8,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogWeekDateTimeVirtualTableRoute:AbstractSimpleShardingWeekKeyDateTimeVirtualTableRoute<LogWeekDateTime>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogWeekTimeLongVirtualTableRoute : AbstractSimpleShardingWeekKeyLongVirtualTableRoute<LogWeekTimeLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogYearDateTimeVirtualRoute:AbstractSimpleShardingYearKeyDateTimeVirtualTableRoute<LogYearDateTime>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override bool AutoCreateTableByTime()
{

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test5x.Shardings
public class LogYearLongVirtualRoute:AbstractSimpleShardingYearKeyLongVirtualTableRoute<LogYearLong>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public override void Configure(EntityMetadataTableBuilder<LogYearLong> builder)
{

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Test5x.Shardings
public class OrderAreaShardingVirtualDataSourceRoute:AbstractShardingOperatorVirtualDataSourceRoute<Order,string>
{
protected override bool EnableHintRoute =>true;
public override bool EnableRouteParseCompileCache => true;
private readonly List<string> _dataSources = new List<string>()
{

View File

@ -9,6 +9,7 @@ namespace ShardingCore.Test5x.Shardings
{
public class OrderCreateTimeVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
{
public override bool EnableRouteParseCompileCache => true;
public override DateTime GetBeginTime()
{
return new DateTime(2021, 1, 1);

View File

@ -12,6 +12,7 @@ namespace ShardingCore.Test5x.Shardings
public class SysUserModIntVirtualRoute:AbstractSimpleShardingModKeyIntVirtualTableRoute<SysUserModInt>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModIntVirtualRoute() : base(2, 3)
{

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Test5x.Shardings
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
{
protected override bool EnableHintRoute => true;
public override bool EnableRouteParseCompileCache => true;
public SysUserModVirtualTableRoute() : base(2,3)
{

View File

@ -16,6 +16,7 @@ namespace ShardingCore.Test5x.Shardings
*/
public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<SysUserSalary,int>
{
public override bool EnableRouteParseCompileCache => true;
public override string ShardingKeyToTail(object shardingKey)
{
var time = Convert.ToInt32(shardingKey);