diff --git a/samples/Sample.AutoCreateIfPresent/Program.cs b/samples/Sample.AutoCreateIfPresent/Program.cs index 3a472cde..089aaa32 100644 --- a/samples/Sample.AutoCreateIfPresent/Program.cs +++ b/samples/Sample.AutoCreateIfPresent/Program.cs @@ -30,6 +30,10 @@ builder.Services.AddShardingDbContext() }) .UseConfig(o => { + // o.CacheEntrySize; + // o.CacheModelLockConcurrencyLevel + // o.CacheModelLockObjectSeconds + // o.CacheItemPriority o.ThrowIfQueryRouteNotMatch = false; o.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=shardingTest;userid=root;password=root;"); o.UseShardingQuery((conn, b) => diff --git a/samples/Sample.MySql/Controllers/WeatherForecastController.cs b/samples/Sample.MySql/Controllers/WeatherForecastController.cs index 3d45d89c..9977f98d 100644 --- a/samples/Sample.MySql/Controllers/WeatherForecastController.cs +++ b/samples/Sample.MySql/Controllers/WeatherForecastController.cs @@ -131,6 +131,7 @@ namespace Sample.MySql.Controllers [HttpGet] public async Task Getxx() { + var test = new Test(); test.UtcTime=DateTime.Now; await _defaultTableDbContext.AddAsync(test); @@ -141,7 +142,7 @@ namespace Sample.MySql.Controllers public async Task Get() { var s = Guid.NewGuid().ToString(); - var page =await _defaultTableDbContext.Set().Where(o=>o.Id==s).OrderByDescending(o=>o.Time).ToShardingPageAsync(1,2); + // var page =await _defaultTableDbContext.Set().Include().ThenInclude().Where(o=>o.Id==s).OrderByDescending(o=>o.Time).ToShardingPageAsync(1,2); // var virtualDataSource = _shardingRuntimeContext.GetVirtualDataSource(); // virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource("2023", "xxxxxxxx", false)); // var dataSourceRouteManager = _shardingRuntimeContext.GetDataSourceRouteManager(); @@ -571,5 +572,15 @@ namespace Sample.MySql.Controllers unShardingDbContext2.SaveChanges(); dbContextTransaction.Commit(); } + + [HttpGet] + public async Task get131() + { + var list = new List(); + var idList = Enumerable.Range(1,50000).Select(o=>o.ToString()).ToList(); + var sysUserMods = _defaultTableDbContext.Set() + .Where(o=>idList.Contains(o.Id)).ToList(); + return Ok(); + } } } diff --git a/samples/Sample.MySql/Shardings/SysUserModVirtualTableRoute.cs b/samples/Sample.MySql/Shardings/SysUserModVirtualTableRoute.cs index 561971b9..b4088070 100644 --- a/samples/Sample.MySql/Shardings/SysUserModVirtualTableRoute.cs +++ b/samples/Sample.MySql/Shardings/SysUserModVirtualTableRoute.cs @@ -24,6 +24,15 @@ namespace Sample.MySql.Shardings builder.ShardingProperty(o => o.Id); } + public override object GetCompareValueByShardingKey(object shardingKey, string shardingPropertyName) + { + if ("Id".Equals(shardingPropertyName)) + { + return ShardingKeyToTail(shardingKey); + } + return base.GetCompareValueByShardingKey(shardingKey, shardingPropertyName); + } + // protected override List AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List shardingRouteUnits) // { // //拦截 diff --git a/samples/Sample.MySql/Startup.cs b/samples/Sample.MySql/Startup.cs index 684dd8ca..7091de91 100644 --- a/samples/Sample.MySql/Startup.cs +++ b/samples/Sample.MySql/Startup.cs @@ -226,7 +226,6 @@ namespace Sample.MySql { app.UseDeveloperExceptionPage(); } - app.ApplicationServices.UseAutoTryCompensateTable(); using (var scope = app.ApplicationServices.CreateScope()) { var unShardingDbContext = scope.ServiceProvider.GetService(); @@ -236,6 +235,7 @@ namespace Sample.MySql // var virtualTableRoute = (SysUserLogByMonthRoute)tableRouteManager.GetRoute(typeof(SysUserLogByMonth)); // virtualTableRoute.Append("2021"); } + app.ApplicationServices.UseAutoTryCompensateTable(); // var shardingRuntimeContext = app.ApplicationServices.GetRequiredService(); // var entityMetadataManager = shardingRuntimeContext.GetEntityMetadataManager(); // var entityMetadata = entityMetadataManager.TryGet(); diff --git a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs index d19bf616..11fa6a81 100644 --- a/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/DataSourceRoutes/Abstractions/AbstractShardingOperatorVirtualDataSourceRoute.cs @@ -24,7 +24,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions protected override List DoRouteWithPredicate(List allDataSourceNames, IQueryable queryable) { //获取路由后缀表达式 - var routeParseExpression = ShardingUtil.GetRouteParseExpression(queryable, EntityMetadata, GetRouteFilter, false); + var routeParseExpression = ShardingUtil.GetRouteParseExpression(queryable, EntityMetadata, GetRouteFilter,GetCompareValueByShardingKey, false); //表达式缓存编译 // var filter = CachingCompile(routeParseExpression); var filter = routeParseExpression.GetRoutePredicate(); @@ -33,6 +33,11 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions return dataSources; } + public virtual object GetCompareValueByShardingKey(object shardingKey, string shardingPropertyName) + { + return shardingKey; + } + /// /// 如何路由到具体表 shardingKeyValue:分表的值, 返回结果:如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表 diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs index 677dcdf5..2a7acd93 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/Abstractions/AbstractShardingOperatorVirtualTableRoute.cs @@ -27,7 +27,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions protected override List DoRouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable) { //获取路由后缀表达式 - var routeParseExpression = ShardingUtil.GetRouteParseExpression(queryable, EntityMetadata, GetRouteFilter,true); + var routeParseExpression = ShardingUtil.GetRouteParseExpression(queryable, EntityMetadata, GetRouteFilter,GetCompareValueByShardingKey,true); //表达式缓存编译 // var filter =CachingCompile(routeParseExpression); var filter =routeParseExpression.GetRoutePredicate(); @@ -40,6 +40,10 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions return sqlRouteUnits; } + public virtual object GetCompareValueByShardingKey(object shardingKey, string shardingPropertyName) + { + return shardingKey; + } /// /// 如何路由到具体表 shardingKeyValue:分表的值, 返回结果:如果返回true表示返回该表 第一个参数 tail 第二参数是否返回该物理表 diff --git a/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs b/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs index 5aa1c128..37927719 100644 --- a/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs +++ b/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs @@ -51,6 +51,7 @@ namespace ShardingCore.Core.Internal.Visitors private readonly EntityMetadata _entityMetadata; private readonly Func> _keyToTailWithFilter; + private readonly Func _compareValueByKey; /// /// 是否是分表路由 @@ -63,10 +64,11 @@ namespace ShardingCore.Core.Internal.Visitors private RoutePredicateExpression _where = RoutePredicateExpression.Default; public QueryableRouteShardingTableDiscoverVisitor(EntityMetadata entityMetadata, - Func> keyToTailWithFilter, bool shardingTableRoute) + Func> keyToTailWithFilter,Func compareValueByKey, bool shardingTableRoute) { _entityMetadata = entityMetadata; _keyToTailWithFilter = keyToTailWithFilter; + _compareValueByKey = compareValueByKey; _shardingTableRoute = shardingTableRoute; } @@ -378,8 +380,15 @@ namespace ShardingCore.Core.Internal.Visitors if (arrayObject is IEnumerable enumerableObj) { + var compareSet = new HashSet(); foreach (var shardingValue in enumerableObj) { + var compareValueByKey = _compareValueByKey(shardingValue,shardingPredicateResult.ShardingPropertyName); + if (!compareSet.Add(compareValueByKey)) + { + continue; + } + var eq = _keyToTailWithFilter(shardingValue, @in ? ShardingOperatorEnum.Equal : ShardingOperatorEnum.NotEqual, shardingPredicateResult.ShardingPropertyName); diff --git a/src/ShardingCore/Utils/ShardingUtil.cs b/src/ShardingCore/Utils/ShardingUtil.cs index 90cafae8..8910630a 100644 --- a/src/ShardingCore/Utils/ShardingUtil.cs +++ b/src/ShardingCore/Utils/ShardingUtil.cs @@ -34,10 +34,10 @@ namespace ShardingCore.Utils /// /// sharding table or data source /// - public static RoutePredicateExpression GetRouteParseExpression(IQueryable queryable, EntityMetadata entityMetadata, Func> keyToTailExpression,bool shardingTableRoute) + public static RoutePredicateExpression GetRouteParseExpression(IQueryable queryable, EntityMetadata entityMetadata, Func> keyToTailExpression,Func compareValueByKey,bool shardingTableRoute) { - QueryableRouteShardingTableDiscoverVisitor visitor = new QueryableRouteShardingTableDiscoverVisitor(entityMetadata, keyToTailExpression, shardingTableRoute); + QueryableRouteShardingTableDiscoverVisitor visitor = new QueryableRouteShardingTableDiscoverVisitor(entityMetadata, keyToTailExpression,compareValueByKey, shardingTableRoute); visitor.Visit(queryable.Expression); diff --git a/test/ShardingCore.CommonTest/ShardingDataSourceMod.cs b/test/ShardingCore.CommonTest/ShardingDataSourceMod.cs index 81b59e92..bca59159 100644 --- a/test/ShardingCore.CommonTest/ShardingDataSourceMod.cs +++ b/test/ShardingCore.CommonTest/ShardingDataSourceMod.cs @@ -24,6 +24,10 @@ namespace ShardingCore.CommonTest _allDataSources = Enumerable.Range(0, 10).Select(o => o.ToString()).ToList(); } + public static object GetCompareValueByShardingKey(object shardingKey, string shardingPropertyName) + { + return shardingKey; + } public static Func GetRouteFilter(object shardingValue, ShardingOperatorEnum shardingOperator, string propertyName) { @@ -47,7 +51,7 @@ namespace ShardingCore.CommonTest private void TestId(IQueryable queryable, string[] dataSourceNames) { var routePredicateExpression = - ShardingUtil.GetRouteParseExpression(queryable, _testEntityMetadata, GetRouteFilter, false); + ShardingUtil.GetRouteParseExpression(queryable, _testEntityMetadata, GetRouteFilter,GetCompareValueByShardingKey, false); Assert.NotNull(routePredicateExpression); var routePredicate = routePredicateExpression.GetRoutePredicate(); diff --git a/test/ShardingCore.CommonTest/ShardingTableTime.cs b/test/ShardingCore.CommonTest/ShardingTableTime.cs index f4f7d19c..72c2b7c2 100644 --- a/test/ShardingCore.CommonTest/ShardingTableTime.cs +++ b/test/ShardingCore.CommonTest/ShardingTableTime.cs @@ -25,6 +25,11 @@ namespace ShardingCore.CommonTest //[20220101....20220120] _allTables = Enumerable.Range(0,20).Select(o=>dateTime.AddDays(o).ToString("yyyyMMdd")).ToList(); } + + public static object GetCompareValueByShardingKey(object shardingKey, string shardingPropertyName) + { + return shardingKey; + } public static Func GetRouteFilter(object shardingValue, ShardingOperatorEnum shardingOperator, string propertyName) { @@ -60,7 +65,7 @@ namespace ShardingCore.CommonTest private void TestId(IQueryable queryable, string[] tables) { - var routePredicateExpression = ShardingUtil.GetRouteParseExpression(queryable,_testEntityMetadata,GetRouteFilter,true); + var routePredicateExpression = ShardingUtil.GetRouteParseExpression(queryable,_testEntityMetadata,GetRouteFilter,GetCompareValueByShardingKey,true); Assert.NotNull(routePredicateExpression); var routePredicate = routePredicateExpression.GetRoutePredicate();