diff --git a/nuget-publish.bat b/nuget-publish.bat index 48378fa9..239baacd 100644 --- a/nuget-publish.bat +++ b/nuget-publish.bat @@ -1,9 +1,9 @@ :start ::定义版本 -set EFCORE2=2.3.2.07 -set EFCORE3=3.3.2.07 -set EFCORE5=5.3.2.07 -set EFCORE6=6.3.2.07 +set EFCORE2=2.3.2.08 +set EFCORE3=3.3.2.08 +set EFCORE5=5.3.2.08 +set EFCORE6=6.3.2.08 ::删除所有bin与obj下的文件 @echo off diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs index 78819589..7b7d23dc 100644 --- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs +++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs @@ -19,12 +19,12 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine { ShardingDbContextType = shardingDbContextType; ReplaceTables = replaceTables.ToHashSet(); - NoDifferentTail = ReplaceTables.IsEmpty() || ReplaceTables.GroupBy(o => o.Tail).Count() == 1; + HasDifferentTail = ReplaceTables.IsNotEmpty() && ReplaceTables.GroupBy(o => o.Tail).Count() != 1; } public ISet ReplaceTables { get; } - public bool NoDifferentTail { get; } + public bool HasDifferentTail { get; } public Type ShardingDbContextType { get; } protected bool Equals(TableRouteResult other) diff --git a/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IMergeQueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IMergeQueryCompilerContext.cs index 9fbd0a74..527c7294 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IMergeQueryCompilerContext.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IMergeQueryCompilerContext.cs @@ -13,11 +13,12 @@ namespace ShardingCore.Sharding.ShardingExecutors.Abstractions public interface IMergeQueryCompilerContext : IQueryCompilerContext { QueryCombineResult GetQueryCombineResult(); - IEnumerable GetTableRouteResults(); + TableRouteResult[] GetTableRouteResults(); DataSourceRouteResult GetDataSourceRouteResult(); bool IsCrossTable(); bool IsCrossDataSource(); bool IsEnumerableQuery(); + bool IsParallelQuery(); } } diff --git a/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs index 045e0d4d..ea099005 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs @@ -24,7 +24,7 @@ namespace ShardingCore.Sharding.ShardingExecutors private readonly IQueryCompilerContext _queryCompilerContext; private readonly QueryCombineResult _queryCombineResult; private readonly DataSourceRouteResult _dataSourceRouteResult; - private readonly IEnumerable _tableRouteResults; + private readonly TableRouteResult[] _tableRouteResults; /// /// 本次查询跨库 @@ -35,6 +35,10 @@ namespace ShardingCore.Sharding.ShardingExecutors /// 本次查询跨表 /// private readonly bool _isCrossTable; + /// + /// 存在一次查询跨多个tail + /// + private readonly bool _existCrossTableTails; private QueryCompilerExecutor _queryCompilerExecutor; @@ -45,9 +49,10 @@ namespace ShardingCore.Sharding.ShardingExecutors _queryCombineResult = queryCombineResult; _parallelTableManager = (IParallelTableManager)ShardingContainer.GetService(typeof(IParallelTableManager<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType())); _dataSourceRouteResult = dataSourceRouteResult; - _tableRouteResults = GetTableRouteResults(tableRouteResults); + _tableRouteResults = GetTableRouteResults(tableRouteResults).ToArray(); _isCrossDataSource = dataSourceRouteResult.IntersectDataSources.Count > 1; - _isCrossTable = _tableRouteResults.Count() > 1|| _tableRouteResults.IsNotEmpty()&& !_tableRouteResults.First().NoDifferentTail; + _isCrossTable = _tableRouteResults.Count() > 1; + _existCrossTableTails = _tableRouteResults.Any(o => o.HasDifferentTail); } private IEnumerable GetTableRouteResults(IEnumerable tableRouteResults) @@ -113,11 +118,12 @@ namespace ShardingCore.Sharding.ShardingExecutors } else { - hasQueryCompilerExecutor = IsSingleDbContextNativeQuery(); - if (hasQueryCompilerExecutor.Value) + hasQueryCompilerExecutor = IsSingleQuery(); + if (hasQueryCompilerExecutor.Value&&(!IsQueryTrack()||!_existCrossTableTails)) { + //要么本次查询不追踪如果需要追踪不可以存在跨tails var routeTailFactory = ShardingContainer.GetService(); - var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), !IsQueryTrack() || CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First())); + var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), IsParallelQuery(), routeTailFactory.Create(_tableRouteResults[0])); _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression()); } } @@ -132,7 +138,7 @@ namespace ShardingCore.Sharding.ShardingExecutors return _queryCombineResult; } - public IEnumerable GetTableRouteResults() + public TableRouteResult[] GetTableRouteResults() { return _tableRouteResults; } @@ -145,20 +151,9 @@ namespace ShardingCore.Sharding.ShardingExecutors /// 既不可以跨库也不可以跨表,所有的分表都必须是相同后缀才可以 /// /// - private bool IsSingleDbContextNativeQuery() + private bool IsSingleQuery() { - return !_isCrossDataSource&&!_isCrossTable && (!IsQueryTrack()|| OnlyShardingDataSourceOrNoDifferentTail()); - } - /// - /// 不存在分表或者分了但是都是一样的tail并且没有不分表的对象 - /// - /// - private bool OnlyShardingDataSourceOrNoDifferentTail() - { - if (GetQueryEntities().All(o => GetEntityMetadataManager().IsOnlyShardingDataSource(o))) - return true; - var firstTableRouteResult = _tableRouteResults.First(); - return (firstTableRouteResult.NoDifferentTail&&GetQueryEntities().All(o=>GetEntityMetadataManager().IsShardingTable(o))); + return !_isCrossDataSource&&!_isCrossTable; } public bool IsCrossTable() @@ -175,5 +170,13 @@ namespace ShardingCore.Sharding.ShardingExecutors { return _queryCompilerContext.IsEnumerableQuery(); } + /// + /// 如果需要聚合并且存在跨tail的查询或者本次是读链接 + /// + /// + public bool IsParallelQuery() + { + return _isCrossTable || _existCrossTableTails|| CurrentQueryReadConnection(); + } } } diff --git a/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs index 41a45800..1660e582 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs @@ -28,6 +28,7 @@ namespace ShardingCore.Sharding.ShardingExecutors private QueryCompilerExecutor _queryCompilerExecutor; private bool? hasQueryCompilerExecutor; private bool? _isNoTracking; + private readonly bool _currentQueryReadConnection; private QueryCompilerContext( IShardingDbContext shardingDbContext, Expression queryExpression) { @@ -39,6 +40,8 @@ namespace ShardingCore.Sharding.ShardingExecutors _entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType)); _shardingConfigOption = ShardingContainer.GetRequiredShardingConfigOption(_shardingDbContextType); + _currentQueryReadConnection = + _shardingConfigOption.UseReadWrite && _shardingDbContext.CurrentIsReadWriteSeparation(); } public static QueryCompilerContext Create(IShardingDbContext shardingDbContext, Expression queryExpression) @@ -73,7 +76,7 @@ namespace ShardingCore.Sharding.ShardingExecutors public bool CurrentQueryReadConnection() { - return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation(); + return _currentQueryReadConnection; } public bool IsQueryTrack() diff --git a/src/ShardingCore/Sharding/StreamMergeContext.cs b/src/ShardingCore/Sharding/StreamMergeContext.cs index 45726e48..6f7ed618 100644 --- a/src/ShardingCore/Sharding/StreamMergeContext.cs +++ b/src/ShardingCore/Sharding/StreamMergeContext.cs @@ -228,12 +228,12 @@ namespace ShardingCore.Sharding } /// - /// 是否使用并行查询 + /// 是否使用并行查询仅分库无所谓可以将分库的当前DbContext进行储存起来但是分表就不行因为一个DbContext最多一对一表 /// /// public bool IsParallelQuery() { - return MergeQueryCompilerContext.IsCrossTable() || MergeQueryCompilerContext.CurrentQueryReadConnection(); + return MergeQueryCompilerContext.IsParallelQuery(); } /// @@ -244,6 +244,8 @@ namespace ShardingCore.Sharding { if (!IsParallelQuery()) return false; + if (MergeQueryCompilerContext.CurrentQueryReadConnection()) + return false; return QueryTrack() && _trackerManager.EntityUseTrack(entityType); } private bool QueryTrack()