修复multi route bug 发布x.3.1.95
This commit is contained in:
parent
6f3ce998e4
commit
b90a240547
|
@ -1,9 +1,9 @@
|
||||||
:start
|
:start
|
||||||
::定义版本
|
::定义版本
|
||||||
set EFCORE2=2.3.1.94
|
set EFCORE2=2.3.1.95
|
||||||
set EFCORE3=3.3.1.94
|
set EFCORE3=3.3.1.95
|
||||||
set EFCORE5=5.3.1.94
|
set EFCORE5=5.3.1.95
|
||||||
set EFCORE6=6.3.1.94
|
set EFCORE6=6.3.1.95
|
||||||
|
|
||||||
::删除所有bin与obj下的文件
|
::删除所有bin与obj下的文件
|
||||||
@echo off
|
@echo off
|
||||||
|
|
|
@ -30,6 +30,11 @@ namespace ShardingCore.Core.EntityMetadatas
|
||||||
return false;
|
return false;
|
||||||
return entityMetadata.IsMultiTableMapping;
|
return entityMetadata.IsMultiTableMapping;
|
||||||
}
|
}
|
||||||
|
public bool IsOnlyShardingTable(Type entityType)
|
||||||
|
{
|
||||||
|
return IsShardingTable(entityType) && !IsShardingDataSource(entityType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象是否是分库对象
|
/// 对象是否是分库对象
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -41,6 +46,11 @@ namespace ShardingCore.Core.EntityMetadatas
|
||||||
return false;
|
return false;
|
||||||
return entityMetadata.IsMultiDataSourceMapping;
|
return entityMetadata.IsMultiDataSourceMapping;
|
||||||
}
|
}
|
||||||
|
public bool IsOnlyShardingDataSource(Type entityType)
|
||||||
|
{
|
||||||
|
return IsShardingDataSource(entityType) && !IsShardingTable(entityType);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 对象获取没有返回null
|
/// 对象获取没有返回null
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -21,12 +21,14 @@ namespace ShardingCore.Core.EntityMetadatas
|
||||||
/// <param name="entityType"></param>
|
/// <param name="entityType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool IsShardingTable(Type entityType);
|
bool IsShardingTable(Type entityType);
|
||||||
|
bool IsOnlyShardingTable(Type entityType);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否分库
|
/// 是否分库
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entityType"></param>
|
/// <param name="entityType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool IsShardingDataSource(Type entityType);
|
bool IsShardingDataSource(Type entityType);
|
||||||
|
bool IsOnlyShardingDataSource(Type entityType);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 尝试获取
|
/// 尝试获取
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -2,10 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ShardingCore.Core.PhysicTables;
|
using ShardingCore.Core.PhysicTables;
|
||||||
|
|
||||||
#if !EFCORE5
|
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
{
|
{
|
||||||
|
@ -21,9 +18,12 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
{
|
{
|
||||||
ShardingDbContextType = shardingDbContextType;
|
ShardingDbContextType = shardingDbContextType;
|
||||||
ReplaceTables = replaceTables.ToHashSet();
|
ReplaceTables = replaceTables.ToHashSet();
|
||||||
|
NoDifferentTail = ReplaceTables.IsEmpty() || ReplaceTables.GroupBy(o => o.Tail).Count() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISet<IPhysicTable> ReplaceTables { get; }
|
public ISet<IPhysicTable> ReplaceTables { get; }
|
||||||
|
|
||||||
|
public bool NoDifferentTail { get; }
|
||||||
public Type ShardingDbContextType { get; }
|
public Type ShardingDbContextType { get; }
|
||||||
protected bool Equals(TableRouteResult other)
|
protected bool Equals(TableRouteResult other)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,10 +67,14 @@ namespace ShardingCore.Extensions
|
||||||
return (IQueryable<T>) source.Provider.CreateQuery(expression);
|
return (IQueryable<T>) source.Provider.CreateQuery(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool? GetIsNoTracking<T>(this IQueryable<T> source)
|
internal static bool? GetIsNoTracking(this IQueryable source)
|
||||||
|
{
|
||||||
|
return GetIsNoTracking(source.Expression);
|
||||||
|
}
|
||||||
|
internal static bool? GetIsNoTracking(this Expression expression)
|
||||||
{
|
{
|
||||||
var queryableTrackingDiscoverVisitor = new QueryableTrackingDiscoverVisitor();
|
var queryableTrackingDiscoverVisitor = new QueryableTrackingDiscoverVisitor();
|
||||||
queryableTrackingDiscoverVisitor.Visit(source.Expression);
|
queryableTrackingDiscoverVisitor.Visit(expression);
|
||||||
return queryableTrackingDiscoverVisitor.IsNoTracking;
|
return queryableTrackingDiscoverVisitor.IsNoTracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,5 +25,7 @@ namespace ShardingCore.Sharding.ShardingExecutors.Abstractions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
bool CurrentQueryReadConnection();
|
bool CurrentQueryReadConnection();
|
||||||
|
|
||||||
|
bool IsQueryTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,21 +97,53 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
||||||
return _queryCompilerContext.CurrentQueryReadConnection();
|
return _queryCompilerContext.CurrentQueryReadConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsQueryTrack()
|
||||||
|
{
|
||||||
|
return _queryCompilerContext.IsQueryTrack();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public QueryCompilerExecutor GetQueryCompilerExecutor()
|
public QueryCompilerExecutor GetQueryCompilerExecutor()
|
||||||
{
|
{
|
||||||
if (!hasQueryCompilerExecutor.HasValue)
|
if (!hasQueryCompilerExecutor.HasValue)
|
||||||
{
|
{
|
||||||
hasQueryCompilerExecutor = !IsMergeQuery();
|
if (_dataSourceRouteResult.IntersectDataSources.IsEmpty() || _tableRouteResults.IsEmpty())
|
||||||
|
{
|
||||||
|
hasQueryCompilerExecutor = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hasQueryCompilerExecutor = IsSingleDbContextNativeQuery();
|
||||||
if (hasQueryCompilerExecutor.Value)
|
if (hasQueryCompilerExecutor.Value)
|
||||||
{
|
{
|
||||||
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
||||||
var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First()));
|
var dbContext = GetShardingDbContext().GetDbContext(_dataSourceRouteResult.IntersectDataSources.First(), !IsQueryTrack() || CurrentQueryReadConnection(), routeTailFactory.Create(_tableRouteResults.First()));
|
||||||
_queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression());
|
_queryCompilerExecutor = new QueryCompilerExecutor(dbContext, GetQueryExpression());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return _queryCompilerExecutor;
|
return _queryCompilerExecutor;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 既不可以跨库也不可以跨表,所有的分表都必须是相同后缀才可以
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool IsSingleDbContextNativeQuery()
|
||||||
|
{
|
||||||
|
return !_isCrossDataSource && !_isCrossTable && (!IsQueryTrack() || OnlyShardingDataSourceOrNoDifferentTail());
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 不存在分表或者分了但是都是一样的tail并且没有不分表的对象
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
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()
|
public QueryCombineResult GetQueryCombineResult()
|
||||||
|
|
|
@ -27,11 +27,13 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
||||||
private readonly IShardingConfigOption _shardingConfigOption;
|
private readonly IShardingConfigOption _shardingConfigOption;
|
||||||
private QueryCompilerExecutor _queryCompilerExecutor;
|
private QueryCompilerExecutor _queryCompilerExecutor;
|
||||||
private bool? hasQueryCompilerExecutor;
|
private bool? hasQueryCompilerExecutor;
|
||||||
|
private bool? _isNoTracking;
|
||||||
|
|
||||||
private QueryCompilerContext( IShardingDbContext shardingDbContext, Expression queryExpression)
|
private QueryCompilerContext( IShardingDbContext shardingDbContext, Expression queryExpression)
|
||||||
{
|
{
|
||||||
_shardingDbContextType = shardingDbContext.GetType();
|
_shardingDbContextType = shardingDbContext.GetType();
|
||||||
_queryEntities = ShardingUtil.GetQueryEntitiesByExpression(queryExpression, _shardingDbContextType);
|
_queryEntities = ShardingUtil.GetQueryEntitiesByExpression(queryExpression, _shardingDbContextType);
|
||||||
|
_isNoTracking = queryExpression.GetIsNoTracking();
|
||||||
_shardingDbContext = shardingDbContext;
|
_shardingDbContext = shardingDbContext;
|
||||||
_queryExpression = queryExpression;
|
_queryExpression = queryExpression;
|
||||||
_entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType));
|
_entityMetadataManager = (IEntityMetadataManager)ShardingContainer.GetService(typeof(IEntityMetadataManager<>).GetGenericType0(_shardingDbContextType));
|
||||||
|
@ -73,6 +75,23 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
||||||
{
|
{
|
||||||
return _shardingConfigOption.UseReadWrite&&_shardingDbContext.CurrentIsReadWriteSeparation();
|
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()
|
public QueryCompilerExecutor GetQueryCompilerExecutor()
|
||||||
{
|
{
|
||||||
if (!hasQueryCompilerExecutor.HasValue)
|
if (!hasQueryCompilerExecutor.HasValue)
|
||||||
|
|
|
@ -55,10 +55,6 @@ namespace ShardingCore.Sharding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ISet<Type> QueryEntities { get; }
|
public ISet<Type> QueryEntities { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 本次查询是否包含notracking
|
|
||||||
/// </summary>
|
|
||||||
public bool? IsNoTracking { get; }
|
|
||||||
/// <summary>
|
|
||||||
/// 本次查询跨库
|
/// 本次查询跨库
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsCrossDataSource { get; }
|
public bool IsCrossDataSource { get; }
|
||||||
|
@ -91,7 +87,6 @@ namespace ShardingCore.Sharding
|
||||||
Skip = reWriteResult.Skip;
|
Skip = reWriteResult.Skip;
|
||||||
Take = reWriteResult.Take;
|
Take = reWriteResult.Take;
|
||||||
Orders = reWriteResult.Orders ?? Enumerable.Empty<PropertyOrder>();
|
Orders = reWriteResult.Orders ?? Enumerable.Empty<PropertyOrder>();
|
||||||
IsNoTracking = _source.GetIsNoTracking();
|
|
||||||
SelectContext = reWriteResult.SelectContext;
|
SelectContext = reWriteResult.SelectContext;
|
||||||
GroupByContext = reWriteResult.GroupByContext;
|
GroupByContext = reWriteResult.GroupByContext;
|
||||||
_reWriteSource = reWriteResult.ReWriteQueryable;
|
_reWriteSource = reWriteResult.ReWriteQueryable;
|
||||||
|
@ -248,18 +243,7 @@ namespace ShardingCore.Sharding
|
||||||
}
|
}
|
||||||
private bool QueryTrack()
|
private bool QueryTrack()
|
||||||
{
|
{
|
||||||
var shardingDbContext = (DbContext)_shardingDbContext;
|
return MergeQueryCompilerContext.IsQueryTrack();
|
||||||
if (!shardingDbContext.ChangeTracker.AutoDetectChangesEnabled)
|
|
||||||
return false;
|
|
||||||
if (IsNoTracking.HasValue)
|
|
||||||
{
|
|
||||||
return !IsNoTracking.Value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return shardingDbContext.ChangeTracker.QueryTrackingBehavior ==
|
|
||||||
QueryTrackingBehavior.TrackAll;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IShardingComparer GetShardingComparer()
|
public IShardingComparer GetShardingComparer()
|
||||||
|
|
Loading…
Reference in New Issue