From b90a240547607365fb5cbf292484857d886ad21e Mon Sep 17 00:00:00 2001
From: xuejiaming <326308290@qq.com>
Date: Thu, 30 Dec 2021 17:35:22 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmulti=20route=20bug=20?=
=?UTF-8?q?=E5=8F=91=E5=B8=83x.3.1.95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
nuget-publish.bat | 8 ++--
.../DefaultEntityMetadataManager.cs | 10 +++++
.../EntityMetadatas/IEntityMetadataManager.cs | 2 +
.../RoutingRuleEngine/TableRouteResult.cs | 8 ++--
.../Extensions/IShardingQueryableExtension.cs | 8 +++-
.../Abstractions/IQueryCompilerContext.cs | 2 +
.../MergeQueryCompilerContext.cs | 42 ++++++++++++++++---
.../ShardingExecutors/QueryCompilerContext.cs | 19 +++++++++
.../Sharding/StreamMergeContext.cs | 18 +-------
9 files changed, 85 insertions(+), 32 deletions(-)
diff --git a/nuget-publish.bat b/nuget-publish.bat
index 40b754cc..0dbde81a 100644
--- a/nuget-publish.bat
+++ b/nuget-publish.bat
@@ -1,9 +1,9 @@
:start
::定义版本
-set EFCORE2=2.3.1.94
-set EFCORE3=3.3.1.94
-set EFCORE5=5.3.1.94
-set EFCORE6=6.3.1.94
+set EFCORE2=2.3.1.95
+set EFCORE3=3.3.1.95
+set EFCORE5=5.3.1.95
+set EFCORE6=6.3.1.95
::删除所有bin与obj下的文件
@echo off
diff --git a/src/ShardingCore/Core/EntityMetadatas/DefaultEntityMetadataManager.cs b/src/ShardingCore/Core/EntityMetadatas/DefaultEntityMetadataManager.cs
index 620b4057..bba20b2b 100644
--- a/src/ShardingCore/Core/EntityMetadatas/DefaultEntityMetadataManager.cs
+++ b/src/ShardingCore/Core/EntityMetadatas/DefaultEntityMetadataManager.cs
@@ -30,6 +30,11 @@ namespace ShardingCore.Core.EntityMetadatas
return false;
return entityMetadata.IsMultiTableMapping;
}
+ public bool IsOnlyShardingTable(Type entityType)
+ {
+ return IsShardingTable(entityType) && !IsShardingDataSource(entityType);
+ }
+
///
/// 对象是否是分库对象
///
@@ -41,6 +46,11 @@ namespace ShardingCore.Core.EntityMetadatas
return false;
return entityMetadata.IsMultiDataSourceMapping;
}
+ public bool IsOnlyShardingDataSource(Type entityType)
+ {
+ return IsShardingDataSource(entityType) && !IsShardingTable(entityType);
+ }
+
///
/// 对象获取没有返回null
///
diff --git a/src/ShardingCore/Core/EntityMetadatas/IEntityMetadataManager.cs b/src/ShardingCore/Core/EntityMetadatas/IEntityMetadataManager.cs
index f415b165..9afd445a 100644
--- a/src/ShardingCore/Core/EntityMetadatas/IEntityMetadataManager.cs
+++ b/src/ShardingCore/Core/EntityMetadatas/IEntityMetadataManager.cs
@@ -21,12 +21,14 @@ namespace ShardingCore.Core.EntityMetadatas
///
///
bool IsShardingTable(Type entityType);
+ bool IsOnlyShardingTable(Type entityType);
///
/// 是否分库
///
///
///
bool IsShardingDataSource(Type entityType);
+ bool IsOnlyShardingDataSource(Type entityType);
///
/// 尝试获取
///
diff --git a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs
index 8d08ddec..4311b4a4 100644
--- a/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs
+++ b/src/ShardingCore/Core/VirtualRoutes/TableRoutes/RoutingRuleEngine/TableRouteResult.cs
@@ -2,10 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using ShardingCore.Core.PhysicTables;
-
-#if !EFCORE5
using ShardingCore.Extensions;
-#endif
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{
@@ -21,9 +18,12 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{
ShardingDbContextType = shardingDbContextType;
ReplaceTables = replaceTables.ToHashSet();
+ NoDifferentTail = ReplaceTables.IsEmpty() || ReplaceTables.GroupBy(o => o.Tail).Count() == 1;
}
-
+
public ISet ReplaceTables { get; }
+
+ public bool NoDifferentTail { get; }
public Type ShardingDbContextType { get; }
protected bool Equals(TableRouteResult other)
{
diff --git a/src/ShardingCore/Extensions/IShardingQueryableExtension.cs b/src/ShardingCore/Extensions/IShardingQueryableExtension.cs
index 4fd1360b..9be29d1f 100644
--- a/src/ShardingCore/Extensions/IShardingQueryableExtension.cs
+++ b/src/ShardingCore/Extensions/IShardingQueryableExtension.cs
@@ -67,10 +67,14 @@ namespace ShardingCore.Extensions
return (IQueryable) source.Provider.CreateQuery(expression);
}
- internal static bool? GetIsNoTracking(this IQueryable source)
+ internal static bool? GetIsNoTracking(this IQueryable source)
+ {
+ return GetIsNoTracking(source.Expression);
+ }
+ internal static bool? GetIsNoTracking(this Expression expression)
{
var queryableTrackingDiscoverVisitor = new QueryableTrackingDiscoverVisitor();
- queryableTrackingDiscoverVisitor.Visit(source.Expression);
+ queryableTrackingDiscoverVisitor.Visit(expression);
return queryableTrackingDiscoverVisitor.IsNoTracking;
}
diff --git a/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs
index 23440577..6876424f 100644
--- a/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs
+++ b/src/ShardingCore/Sharding/ShardingExecutors/Abstractions/IQueryCompilerContext.cs
@@ -25,5 +25,7 @@ namespace ShardingCore.Sharding.ShardingExecutors.Abstractions
///
///
bool CurrentQueryReadConnection();
+
+ bool IsQueryTrack();
}
}
diff --git a/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs
index fbae0290..4014e2b5 100644
--- a/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs
+++ b/src/ShardingCore/Sharding/ShardingExecutors/MergeQueryCompilerContext.cs
@@ -97,21 +97,53 @@ namespace ShardingCore.Sharding.ShardingExecutors
return _queryCompilerContext.CurrentQueryReadConnection();
}
+ public bool IsQueryTrack()
+ {
+ return _queryCompilerContext.IsQueryTrack();
+ }
+
+
public QueryCompilerExecutor GetQueryCompilerExecutor()
{
if (!hasQueryCompilerExecutor.HasValue)
{
- hasQueryCompilerExecutor = !IsMergeQuery();
- if (hasQueryCompilerExecutor.Value)
+ if (_dataSourceRouteResult.IntersectDataSources.IsEmpty() || _tableRouteResults.IsEmpty())
{
- var routeTailFactory = ShardingContainer.GetService();
- var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First()));
- _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression());
+ hasQueryCompilerExecutor = false;
+ }
+ else
+ {
+ hasQueryCompilerExecutor = IsSingleDbContextNativeQuery();
+ if (hasQueryCompilerExecutor.Value)
+ {
+ var routeTailFactory = ShardingContainer.GetService();
+ var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), !IsQueryTrack() || CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First()));
+ _queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression());
+ }
}
}
return _queryCompilerExecutor;
}
+ ///
+ /// 既不可以跨库也不可以跨表,所有的分表都必须是相同后缀才可以
+ ///
+ ///
+ private bool IsSingleDbContextNativeQuery()
+ {
+ 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)));
+ }
public QueryCombineResult GetQueryCombineResult()
diff --git a/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs b/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs
index f4dd383a..41a45800 100644
--- a/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs
+++ b/src/ShardingCore/Sharding/ShardingExecutors/QueryCompilerContext.cs
@@ -27,11 +27,13 @@ namespace ShardingCore.Sharding.ShardingExecutors
private readonly IShardingConfigOption _shardingConfigOption;
private QueryCompilerExecutor _queryCompilerExecutor;
private bool? hasQueryCompilerExecutor;
+ private bool? _isNoTracking;
private QueryCompilerContext( IShardingDbContext shardingDbContext, Expression queryExpression)
{
_shardingDbContextType = shardingDbContext.GetType();
_queryEntities = ShardingUtil.GetQueryEntitiesByExpression(queryExpression, _shardingDbContextType);
+ _isNoTracking = queryExpression.GetIsNoTracking();
_shardingDbContext = shardingDbContext;
_queryExpression = queryExpression;
_entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType));
@@ -73,6 +75,23 @@ namespace ShardingCore.Sharding.ShardingExecutors
{
return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation();
}
+
+ public bool IsQueryTrack()
+ {
+ var shardingDbContext = (DbContext)_shardingDbContext;
+ if (!shardingDbContext.ChangeTracker.AutoDetectChangesEnabled)
+ return false;
+ if (_isNoTracking.HasValue)
+ {
+ return !_isNoTracking.Value;
+ }
+ else
+ {
+ return shardingDbContext.ChangeTracker.QueryTrackingBehavior ==
+ QueryTrackingBehavior.TrackAll;
+ }
+ }
+
public QueryCompilerExecutor GetQueryCompilerExecutor()
{
if (!hasQueryCompilerExecutor.HasValue)
diff --git a/src/ShardingCore/Sharding/StreamMergeContext.cs b/src/ShardingCore/Sharding/StreamMergeContext.cs
index 532d9928..c70e42ed 100644
--- a/src/ShardingCore/Sharding/StreamMergeContext.cs
+++ b/src/ShardingCore/Sharding/StreamMergeContext.cs
@@ -55,10 +55,6 @@ namespace ShardingCore.Sharding
///
public ISet QueryEntities { get; }
///
- /// 本次查询是否包含notracking
- ///
- public bool? IsNoTracking { get; }
- ///
/// 本次查询跨库
///
public bool IsCrossDataSource { get; }
@@ -91,7 +87,6 @@ namespace ShardingCore.Sharding
Skip = reWriteResult.Skip;
Take = reWriteResult.Take;
Orders = reWriteResult.Orders ?? Enumerable.Empty();
- IsNoTracking = _source.GetIsNoTracking();
SelectContext = reWriteResult.SelectContext;
GroupByContext = reWriteResult.GroupByContext;
_reWriteSource = reWriteResult.ReWriteQueryable;
@@ -248,18 +243,7 @@ namespace ShardingCore.Sharding
}
private bool QueryTrack()
{
- var shardingDbContext = (DbContext)_shardingDbContext;
- if (!shardingDbContext.ChangeTracker.AutoDetectChangesEnabled)
- return false;
- if (IsNoTracking.HasValue)
- {
- return !IsNoTracking.Value;
- }
- else
- {
- return shardingDbContext.ChangeTracker.QueryTrackingBehavior ==
- QueryTrackingBehavior.TrackAll;
- }
+ return MergeQueryCompilerContext.IsQueryTrack();
}
public IShardingComparer GetShardingComparer()