修复动态添加表后缀前后出现延迟的情况下出现的bug,发布x.4.2.12

This commit is contained in:
xuejiaming 2022-04-28 16:31:07 +08:00
parent 10702a38aa
commit 062f823bbf
10 changed files with 125 additions and 40 deletions

View File

@ -1,9 +1,9 @@
:start
::定义版本
set EFCORE2=2.4.2.11
set EFCORE3=3.4.2.11
set EFCORE5=5.4.2.11
set EFCORE6=6.4.2.11
set EFCORE2=2.4.2.12
set EFCORE3=3.4.2.12
set EFCORE5=5.4.2.12
set EFCORE6=6.4.2.12
::删除所有bin与obj下的文件
@echo off

View File

@ -166,7 +166,7 @@ namespace Sample.SqlServer.Controllers
.Union(_defaultTableDbContext.Set<SysUserSalary>().Select(o => new UnionUserId() { UserId = o.UserId })).UseUnionAllMerge().CountAsync();
var hashSet = unionUserIds.Select(o => o.UserId).ToHashSet();
var hashSetCount = hashSet.Count;
var averageAsync = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Age != 19).AverageAsync(o => o.Age);
return Ok();

View File

@ -1,3 +1,4 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
@ -8,6 +9,8 @@ using Microsoft.Extensions.Logging;
using Sample.SqlServerShardingDataSource.VirtualRoutes;
using ShardingCore;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ShardingCore.TableExists;
namespace Sample.SqlServerShardingDataSource
@ -34,8 +37,8 @@ namespace Sample.SqlServerShardingDataSource
services.AddShardingDbContext<MyDbContext>()
.AddEntityConfig(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.CreateShardingTableOnStart = false;
o.EnsureCreatedWithOutShardingTable = false;
o.AddShardingDataSourceRoute<OrderVirtualDataSourceRoute>();
o.AddShardingDataSourceRoute<SysUserVirtualDataSourceRoute>();
})
@ -51,21 +54,14 @@ namespace Sample.SqlServerShardingDataSource
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
});
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MyDbContext>());
op.AddDefaultDataSource("A",
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceDBA;Integrated Security=True;");
op.AddDefaultDataSource("00",
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceOnly00;Integrated Security=True;");
op.AddExtraDataSource(sp =>
{
return new Dictionary<string, string>()
{
{
"B",
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceDBB;Integrated Security=True;"
},
{
"C",
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceDBC;Integrated Security=True;"
},
};
return Enumerable.Range(1, 100).Select(o => (o % 100).ToString().PadLeft(2, '0')).ToList()
.ToDictionary(o => o,
o =>
$"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceOnly{o};Integrated Security=True;");
});
}).EnsureConfig();
}
@ -78,7 +74,10 @@ namespace Sample.SqlServerShardingDataSource
app.UseDeveloperExceptionPage();
}
Stopwatch sp=Stopwatch.StartNew();
app.UseShardingCore();
sp.Stop();
Console.WriteLine("şÄĘą"+sp.ElapsedMilliseconds);
app.UseRouting();
app.UseAuthorization();
@ -87,7 +86,7 @@ namespace Sample.SqlServerShardingDataSource
{
endpoints.MapControllers();
});
app.InitSeed();
//app.InitSeed();
}
}
}

View File

@ -11,10 +11,7 @@ namespace Sample.SqlServerShardingDataSource.VirtualRoutes
{
public class OrderVirtualDataSourceRoute : AbstractShardingOperatorVirtualDataSourceRoute<Order, string>
{
private readonly List<string> _dataSources = new List<string>()
{
"A", "B", "C"
};
private readonly List<string> _dataSources = Enumerable.Range(0,100).Select(o=>(o % 100).ToString().PadLeft(2,'0')).ToList();
//我们设置区域就是数据库
public override string ShardingKeyToDataSourceName(object shardingKey)
{

View File

@ -17,7 +17,7 @@ namespace Sample.SqlServerShardingTable.VirtualRoutes
public override string ShardingKeyToTail(object shardingKey)
{
var stringHashCode = ShardingCoreHelper.GetStringHashCode("123");
var stringHashCode = ShardingCoreHelper.GetStringHashCode(shardingKey.ToString());
var hashCode = stringHashCode % 10000;
if (hashCode >= 0 && hashCode <= 3000)
{

View File

@ -43,11 +43,9 @@ namespace ShardingCore.EFCores
{
var singleQueryRouteTail = (ISingleQueryRouteTail) shardingTableDbContext.RouteTail;
var tail = singleQueryRouteTail.GetTail();
var virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
var typeMap = virtualTableManager.GetAllVirtualTables().Where(o => o.GetTableAllTails().Contains(tail)).Select(o => o.EntityMetadata.EntityType).ToHashSet();
//设置分表
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => _entityMetadataManager.IsShardingTable(o.ClrType) && typeMap.Contains(o.ClrType)).ToArray();
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => _entityMetadataManager.IsShardingTable(o.ClrType)).ToArray();
foreach (var entityType in mutableEntityTypes)
{
MappingToTable(entityType.ClrType, modelBuilder, tail);

View File

@ -8,6 +8,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
@ -42,6 +43,58 @@ namespace ShardingCore.Sharding.StreamMergeEngines.AggregateMergeEngines
},
cancellationToken)).Where(o => o.QueryResult != null).ToList();
// return (await base.ExecuteAsync(
// async queryable =>
// {
// var count = 0L;
// T sum = default;
// //MethodInfo sumMethod = typeof(Queryable).GetMethods().First(
// // m => m.Name == nameof(Queryable.Sum)
// // && m.ReturnType == typeof(T)
// // && m.IsGenericMethod);
// //var genericSumMethod = sumMethod.MakeGenericMethod(new[] { source.ElementType });
// var newQueryable = ((IQueryable<T>)queryable).Select(o=>(decimal?)(object)o);
//#if !EFCORE2
// var r = await newQueryable.GroupBy(o=>1).Select(o=>new
// {
// C= o.LongCount(),
// //S = ShardingEntityFrameworkQueryableExtensions.Execute<T,T>(ShardingQueryableMethods.GetSumWithoutSelector(typeof(T)), newQueryable, (Expression)null)
// S = o.Sum()
// }).FirstOrDefaultAsync(cancellationToken);
// ////https://stackoverflow.com/questions/21143179/build-groupby-expression-tree-with-multiple-fields
// ////https://blog.wiseowls.co.nz/index.php/2021/05/13/ef-core-3-1-dynamic-groupby-clause/
// ////https://blog.wiseowls.co.nz/index.php/2021/05/13/ef-core-3-1-dynamic-groupby-clause/
// ////https://stackoverflow.com/questions/39728898/groupby-query-by-linq-expressions-and-lambdas
// // Expression.New(
// // Type.GetType("System.Tuple`" + fields.Length)
// // .MakeGenericType(fields.Select(studentType.GetProperty),
// // fields.Select(f => Expression.PropertyOrField(itemParam, f))
// // )
// // if (r != null)
// // {
// // count = r.C;
// // //sum = r.S;
// // }
//#endif
//#if EFCORE2
// count = await ((IQueryable<T>)queryable).LongCountAsync(cancellationToken);
// if (count <= 0)
// {
// return default;
// }
// sum = await GetSumAsync<T>(queryable, cancellationToken);
//#endif
// return new AverageResult<T>(sum, count);
// },
// cancellationToken)).Where(o => o.QueryResult != null).ToList();
}
private async Task<T> GetSumAsync<T>(IQueryable queryable,

View File

@ -55,6 +55,38 @@ namespace ShardingCore.Sharding
CancellationToken cancellationToken1 = cancellationToken;
return provider.ExecuteAsync<TResult>((Expression)methodCallExpression, cancellationToken1);
}
public static TResult Execute<TSource, TResult>(
MethodInfo operatorMethodInfo,
IQueryable<TSource> source,
Expression? expression)
{
if (!(source.Provider is IAsyncQueryProvider provider))
throw new InvalidOperationException(CoreStrings.IQueryableProviderNotAsync);
if (operatorMethodInfo.IsGenericMethod)
{
MethodInfo methodInfo;
if (operatorMethodInfo.GetGenericArguments().Length != 2)
methodInfo = operatorMethodInfo.MakeGenericMethod(typeof(TSource));
else
methodInfo = operatorMethodInfo.MakeGenericMethod(typeof(TSource), ((IEnumerable<Type>)typeof(TResult).GetGenericArguments()).Single<Type>());
operatorMethodInfo = methodInfo;
}
MethodInfo method = operatorMethodInfo;
Expression[] expressionArray;
if (expression != null)
expressionArray = new Expression[2]
{
source.Expression,
expression
};
else
expressionArray = new Expression[1]
{
source.Expression
};
MethodCallExpression methodCallExpression = Expression.Call((Expression)null, method, expressionArray);
return provider.Execute<TResult>((Expression)methodCallExpression);
}
#endif
@ -74,6 +106,17 @@ namespace ShardingCore.Sharding
CancellationToken cancellationToken1 = cancellationToken;
return provider.ExecuteAsync<TResult>((Expression) methodCallExpression, cancellationToken1);
}
public static TResult Execute<TSource, TResult>(
MethodInfo operatorMethodInfo,
IQueryable<TSource> source)
{
if (!(source.Provider is IAsyncQueryProvider provider))
throw new InvalidOperationException(CoreStrings.IQueryableProviderNotAsync);
if (operatorMethodInfo.IsGenericMethod)
operatorMethodInfo = operatorMethodInfo.MakeGenericMethod(typeof (TSource));
MethodCallExpression methodCallExpression = Expression.Call((Expression) null, operatorMethodInfo, source.Expression);
return provider.Execute<TResult>((Expression) methodCallExpression);
}
#endif
}
}

View File

@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.Exceptions;
@ -13,7 +6,9 @@ using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ShardingExecutors.Abstractions;
using ShardingCore.Sharding.ShardingExecutors.QueryableCombines;
using ShardingCore.Sharding.Visitors;
using System;
using System.Linq;
using System.Linq.Expressions;
namespace ShardingCore.Sharding.ShardingExecutors
{