From be9476e591ffb9a74e6696e096bc313f17b178d6 Mon Sep 17 00:00:00 2001 From: xuejiaming <326308290@qq.com> Date: Tue, 30 Nov 2021 16:11:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BB=E5=86=99=E5=88=86?= =?UTF-8?q?=E7=A6=BB=E6=94=AF=E6=8C=81=E6=9D=83=E9=87=8D=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?,=E4=BC=98=E5=8C=96sum=E5=92=8Caverage=E7=9A=84=E8=A3=85?= =?UTF-8?q?=E7=AE=B1=E6=8B=86=E7=AE=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- samples/Sample.SqlServer/Startup.cs | 2 +- .../ShardingReadWriteSeparationBuilder.cs | 2 +- .../AggregateExtensions/AggregateExtension.cs | 77 ++++++++++++++++--- .../AverageAsyncInMemoryMergeEngine.cs | 6 +- .../SumAsyncInMemoryMergeEngine.cs | 2 +- src/ShardingCore/ShardingConfigOption.cs | 4 +- test/ShardingCore.Test/ShardingTest.cs | 1 + test/ShardingCore.Test/Startup.cs | 2 +- test/ShardingCore.Test2x/Startup.cs | 2 +- test/ShardingCore.Test3x/Startup.cs | 2 +- test/ShardingCore.Test5x/Startup.cs | 2 +- 11 files changed, 79 insertions(+), 23 deletions(-) diff --git a/samples/Sample.SqlServer/Startup.cs b/samples/Sample.SqlServer/Startup.cs index b253a8b6..0907c0f3 100644 --- a/samples/Sample.SqlServer/Startup.cs +++ b/samples/Sample.SqlServer/Startup.cs @@ -51,7 +51,7 @@ namespace Sample.SqlServer o.AddShardingTableRoute(); }).AddReadWriteSeparation(sp => { - return new Dictionary>() + return new Dictionary>() { {"ds0",new HashSet(){"Data Source=localhost;Initial Catalog=ShardingCoreDB1;Integrated Security=True;"}} }; diff --git a/src/ShardingCore/DIExtensions/ShardingReadWriteSeparationBuilder.cs b/src/ShardingCore/DIExtensions/ShardingReadWriteSeparationBuilder.cs index ada3c8ca..d33ed597 100644 --- a/src/ShardingCore/DIExtensions/ShardingReadWriteSeparationBuilder.cs +++ b/src/ShardingCore/DIExtensions/ShardingReadWriteSeparationBuilder.cs @@ -26,7 +26,7 @@ namespace ShardingCore.DIExtensions } public ShardingCoreConfigEndBuilder AddReadWriteSeparation( - Func>> readWriteSeparationConfigure, + Func>> readWriteSeparationConfigure, ReadStrategyEnum readStrategyEnum, bool defaultEnable = false, int defaultPriority = 10, diff --git a/src/ShardingCore/Sharding/Enumerators/AggregateExtensions/AggregateExtension.cs b/src/ShardingCore/Sharding/Enumerators/AggregateExtensions/AggregateExtension.cs index 7e3551eb..30bd3544 100644 --- a/src/ShardingCore/Sharding/Enumerators/AggregateExtensions/AggregateExtension.cs +++ b/src/ShardingCore/Sharding/Enumerators/AggregateExtensions/AggregateExtension.cs @@ -99,14 +99,8 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions return source.Count(property); } - /// - /// 根据属性求和 - /// - /// - /// - /// - /// - public static object SumByProperty(this IQueryable source, PropertyInfo property) + + private static MethodCallExpression CreateSumByProperty(this IQueryable source, PropertyInfo property) { if (source == null) throw new ArgumentNullException(nameof(source)); if (property == null) throw new ArgumentNullException(nameof(property)); @@ -121,15 +115,31 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions && m.ReturnType == property.PropertyType && m.IsGenericMethod); - var genericSumMethod = sumMethod.MakeGenericMethod(new[] {source.ElementType}); + var genericSumMethod = sumMethod.MakeGenericMethod(new[] { source.ElementType }); var callExpression = Expression.Call( null, genericSumMethod, - new[] {source.Expression, Expression.Quote(selector)}); - + new[] { source.Expression, Expression.Quote(selector) }); + return callExpression; + } + /// + /// 根据属性求和 + /// + /// + /// + /// + /// + public static object SumByProperty(this IQueryable source, PropertyInfo property) + { + var callExpression = CreateSumByProperty(source, property); return source.Provider.Execute(callExpression); } + public static TSelect SumByProperty(this IQueryable source, PropertyInfo property) + { + var callExpression = CreateSumByProperty(source, property); + return source.Provider.Execute(callExpression); + } /// /// 根据属性求和 /// @@ -145,6 +155,22 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions PropertyInfo property = source.ElementType.GetProperty(propertyName); return source.SumByProperty(property); } + /// + /// 对 + /// + /// + /// + /// + /// + /// + public static TSelect SumByPropertyName(this IQueryable source, string propertyName) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + if (propertyName == null) throw new ArgumentNullException(nameof(propertyName)); + + PropertyInfo property = source.ElementType.GetProperty(propertyName); + return source.SumByProperty(property); + } //public static object Average(this IQueryable source, string member) //{ // if (source == null) throw new ArgumentNullException(nameof(source)); @@ -312,6 +338,35 @@ namespace ShardingCore.Sharding.Enumerators.AggregateExtensions var invoke = Expression.Lambda(binaryExpression).Compile().DynamicInvoke(); return invoke; } + public static TResult AverageConstant(TSum sum, TCount count) + { + var resultType = typeof(TResult); + Expression constantSum = Expression.Constant(sum); + //如果计算类型和返回类型不一致先转成一致 + if (sum.GetType() != resultType) + constantSum = Expression.Convert(constantSum, resultType); + Expression constantCount = Expression.Constant(count); + //如果计算类型和返回类型不一致先转成一致 + if (count.GetType() != resultType) + constantCount = Expression.Convert(constantCount, resultType); + var binaryExpression = Expression.Divide(constantSum, constantCount); + var invoke = Expression.Lambda>(binaryExpression).Compile()(); + return invoke; + } + //private static readonly Type _divideFirstDecimalType=typeof(decimal); + //private static readonly Type _divideSecondDoubleType=typeof(double); + //private static readonly Type _divideThirdFloatType=typeof(float); + //private static Type GetConvertPriorityType(Type sum, Type count, Type result) + //{ + // if (_divideFirstDecimalType == sum || _divideFirstDecimalType == count || _divideFirstDecimalType == result) + // return _divideFirstDecimalType; + // if (_divideSecondDoubleType == sum || _divideSecondDoubleType == count || _divideSecondDoubleType == result) + // return _divideSecondDoubleType; + // if (_divideThirdFloatType == sum || _divideThirdFloatType == count || _divideThirdFloatType == result) + // return _divideThirdFloatType; + // return result; + //} + /// /// 获取平均数和 [{avg1,sum1},{avg2,sum2}....]=>sum(sum1...n)/sum(sum1...n/avg1...n) /// diff --git a/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/AverageAsyncInMemoryMergeEngine.cs b/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/AverageAsyncInMemoryMergeEngine.cs index 23c678dd..76878cea 100644 --- a/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/AverageAsyncInMemoryMergeEngine.cs +++ b/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/AverageAsyncInMemoryMergeEngine.cs @@ -85,9 +85,9 @@ namespace ShardingCore.Sharding.StreamMergeEngines.AggregateMergeEngines Sum = o.QueryResult.Sum, Count = o.QueryResult.Count }).AsQueryable(); - var sum = queryable.SumByPropertyName(nameof(AverageResult.Sum)); - var count = queryable.SumByPropertyName(nameof(AverageResult.Count)); - return (TEnsureResult)AggregateExtension.AverageConstant(sum, count,typeof(TEnsureResult)); + var sum = queryable.SumByPropertyName(nameof(AverageResult.Sum)); + var count = queryable.Sum(o => o.Count); + return AggregateExtension.AverageConstant(sum, count); } } diff --git a/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/SumAsyncInMemoryMergeEngine.cs b/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/SumAsyncInMemoryMergeEngine.cs index 88554388..c246d2f8 100644 --- a/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/SumAsyncInMemoryMergeEngine.cs +++ b/src/ShardingCore/Sharding/MergeEngines/AggregateMergeEngines/SumAsyncInMemoryMergeEngine.cs @@ -57,7 +57,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.AggregateMergeEngines { if (source.IsEmpty()) return default; - var sum = source.AsQueryable().SumByPropertyName(nameof(RouteQueryResult.QueryResult)); + var sum = source.AsQueryable().SumByPropertyName(nameof(RouteQueryResult.QueryResult)); return ConvertSum(sum); } private TEnsureResult ConvertSum(TNumber number) diff --git a/src/ShardingCore/ShardingConfigOption.cs b/src/ShardingCore/ShardingConfigOption.cs index 8434471e..c9cd21ee 100644 --- a/src/ShardingCore/ShardingConfigOption.cs +++ b/src/ShardingCore/ShardingConfigOption.cs @@ -71,7 +71,7 @@ namespace ShardingCore //} public bool UseReadWrite => ReadConnStringConfigure != null; - public Func>> ReadConnStringConfigure { get; private set; } + public Func>> ReadConnStringConfigure { get; private set; } public ReadStrategyEnum ReadStrategyEnum { get; private set; } public bool ReadWriteDefaultEnable { get; private set; } public int ReadWriteDefaultPriority { get; private set; } @@ -85,7 +85,7 @@ namespace ShardingCore /// 鑰冭檻鍒板緢澶氭椂鍊欒鍐欏垎绂荤殑寤惰繜闇瑕侀┈涓婄敤鍒板啓鍏ョ殑鏁版嵁鎵浠ラ粯璁ゅ叧闂渶瑕佺殑璇濊嚜宸卞紑鍚垨鑰呴氳繃IShardingReadWriteManager,false琛ㄧず榛樿涓嶈蛋璇诲啓鍒嗙闄ら潪浣犺嚜宸卞紑鍚,true琛ㄧず榛樿璧拌鍐欏垎绂婚櫎闈炰綘绂佺敤, /// IShardingReadWriteManager.CreateScope()浼氬垽鏂璬bcontext鐨刾riority鐒跺悗鍒ゆ柇鏄惁鍚敤readwrite /// 璇诲啓鍒嗙鍙兘浼氶犳垚姣忔鏌ヨ涓嶄竴鏍风敋鑷冲垎琛ㄥ悗鐨勫垎椤典細鏈夐敊浣嶉棶棰橈紝鍥犱负浠栦笉鏄竴涓師瀛愭搷浣,鎵浠ュ鏋滄暣涓姹備负涓娆¤鍐欏垏鎹㈠ぇ澶氭暟鏇村姞鍚堥 - public void UseReadWriteConfiguration(Func>> readConnStringConfigure, ReadStrategyEnum readStrategyEnum, bool defaultEnable = false, int defaultPriority = 10, ReadConnStringGetStrategyEnum readConnStringGetStrategy = ReadConnStringGetStrategyEnum.LatestFirstTime) + public void UseReadWriteConfiguration(Func>> readConnStringConfigure, ReadStrategyEnum readStrategyEnum, bool defaultEnable = false, int defaultPriority = 10, ReadConnStringGetStrategyEnum readConnStringGetStrategy = ReadConnStringGetStrategyEnum.LatestFirstTime) { ReadConnStringConfigure = readConnStringConfigure ?? throw new ArgumentNullException(nameof(readConnStringConfigure)); ReadStrategyEnum = readStrategyEnum; diff --git a/test/ShardingCore.Test/ShardingTest.cs b/test/ShardingCore.Test/ShardingTest.cs index f11c67c5..df6d9868 100644 --- a/test/ShardingCore.Test/ShardingTest.cs +++ b/test/ShardingCore.Test/ShardingTest.cs @@ -899,6 +899,7 @@ namespace ShardingCore.Test [Fact] public async Task OrderReadWrite() { + //切换到只读数据库,只读数据库又只配置了A数据源读取B数据源 _virtualDbContext.ReadWriteSeparationReadOnly(); var list = await _virtualDbContext.Set().Where(o => o.Money == 1).ToListAsync(); diff --git a/test/ShardingCore.Test/Startup.cs b/test/ShardingCore.Test/Startup.cs index 6700661b..54d0e703 100644 --- a/test/ShardingCore.Test/Startup.cs +++ b/test/ShardingCore.Test/Startup.cs @@ -73,7 +73,7 @@ namespace ShardingCore.Test op.AddShardingTableRoute(); }).AddReadWriteSeparation(sp => { - return new Dictionary>() + return new Dictionary>() { { "A", new HashSet() diff --git a/test/ShardingCore.Test2x/Startup.cs b/test/ShardingCore.Test2x/Startup.cs index 5d06c851..52ad989b 100644 --- a/test/ShardingCore.Test2x/Startup.cs +++ b/test/ShardingCore.Test2x/Startup.cs @@ -69,7 +69,7 @@ namespace ShardingCore.Test2x op.AddShardingTableRoute(); }).AddReadWriteSeparation(sp => { - return new Dictionary>() + return new Dictionary>() { { "A", new HashSet() diff --git a/test/ShardingCore.Test3x/Startup.cs b/test/ShardingCore.Test3x/Startup.cs index d2d481b1..af59b2ac 100644 --- a/test/ShardingCore.Test3x/Startup.cs +++ b/test/ShardingCore.Test3x/Startup.cs @@ -69,7 +69,7 @@ namespace ShardingCore.Test3x op.AddShardingTableRoute(); }).AddReadWriteSeparation(sp => { - return new Dictionary>() + return new Dictionary>() { { "A", new HashSet() diff --git a/test/ShardingCore.Test5x/Startup.cs b/test/ShardingCore.Test5x/Startup.cs index 782a3c25..a252aed4 100644 --- a/test/ShardingCore.Test5x/Startup.cs +++ b/test/ShardingCore.Test5x/Startup.cs @@ -69,7 +69,7 @@ namespace ShardingCore.Test5x op.AddShardingTableRoute(); }).AddReadWriteSeparation(sp => { - return new Dictionary>() + return new Dictionary>() { { "A", new HashSet()