添加shardingrouteresult

This commit is contained in:
xuejiaming 2022-06-29 10:08:05 +08:00
parent 3b4da3a7ef
commit e8596eabdc
13 changed files with 185 additions and 65 deletions

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Core.VirtualRoutes
{
public class ShardingRouteResult
{
public IReadOnlyList<ISqlRouteUnit> RouteUnits { get; }
public bool IsCrossDataSource { get; }
public bool IsCrossTable { get; }
public bool ExistCrossTableTails { get; }
public bool IsEmpty { get; }
public ShardingRouteResult(List<ISqlRouteUnit> routeUnits,bool isEmpty,bool isCrossDataSource,bool isCrossTable,bool existCrossTableTails)
{
var routeUnitGroup = routeUnits.GroupBy(o=>o.DataSourceName);
RouteUnits = routeUnits;
var count = routeUnitGroup.Count();
IsEmpty =isEmpty;
IsCrossDataSource = isCrossDataSource;
IsCrossTable = isCrossTable;
ExistCrossTableTails=existCrossTableTails;
}
public override string ToString()
{
return string.Join(",", Environment.NewLine,RouteUnits.Select(o => o.ToString()));
}
}
}
//
// _isCrossDataSource = _sqlRouteUnits.Length > 1;
// _isCrossTable = _sqlRouteUnits.Any(o=>o.TableRouteResult.ReplaceTables.Count>1);
// _existCrossTableTails =_sqlRouteUnits.Any(o=>o.TableRouteResult.HasDifferentTail);

View File

@ -4,18 +4,20 @@ namespace ShardingCore.Core.VirtualRoutes
{ {
public sealed class ShardingRouteUnit public sealed class ShardingRouteUnit
{ {
public ShardingRouteUnit(string dataSourceName, string tail) public ShardingRouteUnit(string dataSourceName, string tail,Type entityType)
{ {
DataSourceName = dataSourceName; DataSourceName = dataSourceName;
Tail = tail; Tail = tail;
EntityType = entityType;
} }
public string DataSourceName { get; } public string DataSourceName { get; }
public string Tail { get;} public string Tail { get;}
public Type EntityType { get; }
private bool Equals(ShardingRouteUnit other) private bool Equals(ShardingRouteUnit other)
{ {
return DataSourceName == other.DataSourceName && Tail == other.Tail; return DataSourceName == other.DataSourceName && Tail == other.Tail && EntityType == other.EntityType;
} }
public override bool Equals(object obj) public override bool Equals(object obj)
@ -25,7 +27,7 @@ namespace ShardingCore.Core.VirtualRoutes
public override int GetHashCode() public override int GetHashCode()
{ {
return HashCode.Combine(DataSourceName, Tail); return HashCode.Combine(DataSourceName, Tail, EntityType);
} }
} }
} }

View File

@ -64,7 +64,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
if (filterTails.IsEmpty()||filterTails.Count!=mustTails.Count) if (filterTails.IsEmpty()||filterTails.Count!=mustTails.Count)
throw new ShardingCoreException( throw new ShardingCoreException(
$" sharding route must error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",mustTails)}]"); $" sharding route must error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",mustTails)}]");
var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new ShardingRouteUnit(dataSourceName,tail))).ToList(); var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new ShardingRouteUnit(dataSourceName,tail,typeof(T)))).ToList();
return shardingRouteUnits; return shardingRouteUnits;
} }
@ -74,7 +74,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
if (filterTails.IsEmpty()||filterTails.Count!=hintTails.Count) if (filterTails.IsEmpty()||filterTails.Count!=hintTails.Count)
throw new ShardingCoreException( throw new ShardingCoreException(
$" sharding route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",hintTails)}]"); $" sharding route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",hintTails)}]");
var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new ShardingRouteUnit(dataSourceName,tail))).ToList(); var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new ShardingRouteUnit(dataSourceName,tail,typeof(T)))).ToList();
return GetFilterTableTails(dataSourceRouteResult, shardingRouteUnits); return GetFilterTableTails(dataSourceRouteResult, shardingRouteUnits);
} }
} }

View File

@ -36,7 +36,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
var sqlRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=> var sqlRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>
GetTails() GetTails()
.Where(o=>filter(FormatTableRouteWithDataSource(dataSourceName,o))) .Where(o=>filter(FormatTableRouteWithDataSource(dataSourceName,o)))
.Select(tail=>new ShardingRouteUnit(dataSourceName,tail)) .Select(tail=>new ShardingRouteUnit(dataSourceName,tail,typeof(TEntity)))
).ToList(); ).ToList();
return sqlRouteUnits; return sqlRouteUnits;
@ -88,7 +88,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
if (filterTails.Count > 1) if (filterTails.Count > 1)
throw new ShardingCoreException($"more than one route match table:{string.Join(",", filterTails)}"); throw new ShardingCoreException($"more than one route match table:{string.Join(",", filterTails)}");
return new ShardingRouteUnit(dataSourceRouteResult.IntersectDataSources.First(), filterTails[0]); return new ShardingRouteUnit(dataSourceRouteResult.IntersectDataSources.First(), filterTails[0],typeof(TEntity));
} }
} }

View File

@ -15,6 +15,6 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
public interface ITableRouteRuleEngine public interface ITableRouteRuleEngine
{ {
ShardingRouteUnit[] Route(TableRouteRuleContext tableRouteRuleContext); ShardingRouteResult Route(TableRouteRuleContext tableRouteRuleContext);
} }
} }

View File

@ -17,7 +17,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
public interface ITableRouteRuleEngineFactory public interface ITableRouteRuleEngineFactory
{ {
//TableRouteRuleContext CreateContext(IQueryable queryable); //TableRouteRuleContext CreateContext(IQueryable queryable);
ISqlRouteUnit[] Route(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,Dictionary<Type,IQueryable> queryEntities); ShardingRouteResult Route(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,Dictionary<Type,IQueryable> queryEntities);
//IEnumerable<TableRouteResult> Route(TableRouteRuleContext ruleContext); //IEnumerable<TableRouteResult> Route(TableRouteRuleContext ruleContext);
} }
} }

View File

@ -13,20 +13,22 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
* @Date: Thursday, 28 January 2021 10:18:09 * @Date: Thursday, 28 January 2021 10:18:09
* @Email: 326308290@qq.com * @Email: 326308290@qq.com
*/ */
public class TableRouteResult:IPrint public class TableRouteResult
{ {
public TableRouteResult(List<IPhysicTable> replaceTables) public TableRouteResult(List<ShardingRouteUnit> replaceTables)
{ {
ReplaceTables = replaceTables.ToHashSet(); ReplaceTables = replaceTables.ToHashSet();
HasDifferentTail = ReplaceTables.IsNotEmpty() && ReplaceTables.GroupBy(o => o.Tail).Count() != 1; HasDifferentTail = ReplaceTables.IsNotEmpty() && ReplaceTables.GroupBy(o => o.Tail).Count() != 1;
IsEmpty = replaceTables.Count == 0;
} }
public TableRouteResult(IPhysicTable replaceTable):this(new List<IPhysicTable>(){replaceTable}) public TableRouteResult(ShardingRouteUnit replaceTable):this(new List<ShardingRouteUnit>(){replaceTable})
{ {
} }
public ISet<IPhysicTable> ReplaceTables { get; } public ISet<ShardingRouteUnit> ReplaceTables { get; }
public bool HasDifferentTail { get; } public bool HasDifferentTail { get; }
public bool IsEmpty { get; }
protected bool Equals(TableRouteResult other) protected bool Equals(TableRouteResult other)
{ {
@ -40,7 +42,8 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
if (obj.GetType() != this.GetType()) return false; if (obj.GetType() != this.GetType()) return false;
return Equals((TableRouteResult)obj); return Equals((TableRouteResult)obj);
} }
public string GetPrintInfo()
public override string ToString()
{ {
return $"(has different tail:{HasDifferentTail},current table:[{string.Join(",", ReplaceTables.Select(o => o.EntityType))}])"; return $"(has different tail:{HasDifferentTail},current table:[{string.Join(",", ReplaceTables.Select(o => o.EntityType))}])";
} }

View File

@ -11,6 +11,7 @@ using ShardingCore.Core.VirtualTables;
using ShardingCore.Exceptions; using ShardingCore.Exceptions;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions; using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
@ -29,7 +30,8 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
private readonly IEntityMetadataManager _entityMetadataManager; private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IShardingDatabaseProvider _shardingDatabaseProvider; private readonly IShardingDatabaseProvider _shardingDatabaseProvider;
public TableRouteRuleEngine(ITableRouteManager tableRouteManager,IVirtualTableManager virtualTableManager,IEntityMetadataManager entityMetadataManager,IShardingDatabaseProvider shardingDatabaseProvider) public TableRouteRuleEngine(ITableRouteManager tableRouteManager, IVirtualTableManager virtualTableManager,
IEntityMetadataManager entityMetadataManager, IShardingDatabaseProvider shardingDatabaseProvider)
{ {
_tableRouteManager = tableRouteManager; _tableRouteManager = tableRouteManager;
_virtualTableManager = virtualTableManager; _virtualTableManager = virtualTableManager;
@ -37,9 +39,10 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
_shardingDatabaseProvider = shardingDatabaseProvider; _shardingDatabaseProvider = shardingDatabaseProvider;
} }
public ShardingRouteUnit[] Route(TableRouteRuleContext tableRouteRuleContext) public ShardingRouteResult Route(TableRouteRuleContext tableRouteRuleContext)
{ {
Dictionary<Type, ISet<ShardingRouteUnit>> routeMaps = new Dictionary<Type, ISet<ShardingRouteUnit>>(); Dictionary<string /*dataSourceName*/, Dictionary<Type /*entityType*/, ISet<ShardingRouteUnit>>> routeMaps =
new Dictionary<string, Dictionary<Type, ISet<ShardingRouteUnit>>>();
var queryEntities = tableRouteRuleContext.QueryEntities; var queryEntities = tableRouteRuleContext.QueryEntities;
@ -49,22 +52,83 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
if (!_entityMetadataManager.IsShardingTable(shardingEntity)) if (!_entityMetadataManager.IsShardingTable(shardingEntity))
continue; continue;
var virtualTableRoute = _tableRouteManager.GetRoute(shardingEntity); var virtualTableRoute = _tableRouteManager.GetRoute(shardingEntity);
var shardingRouteUnits = virtualTableRoute.RouteWithPredicate(tableRouteRuleContext.DataSourceRouteResult,(shardingEntityKv.Value ?? tableRouteRuleContext.Queryable),true); var shardingRouteUnits = virtualTableRoute.RouteWithPredicate(
tableRouteRuleContext.DataSourceRouteResult,
if (!routeMaps.ContainsKey(shardingEntity)) (shardingEntityKv.Value ?? tableRouteRuleContext.Queryable), true);
foreach (var shardingRouteUnit in shardingRouteUnits)
{ {
routeMaps.Add(shardingEntity, shardingRouteUnits.ToHashSet()); var dataSourceName = shardingRouteUnit.DataSourceName;
if (!routeMaps.ContainsKey(dataSourceName))
{
routeMaps.Add(dataSourceName,
new Dictionary<Type, ISet<ShardingRouteUnit>>()
{ { shardingEntity, new HashSet<ShardingRouteUnit>() { shardingRouteUnit } } });
} }
else else
{ {
foreach (var shardingRouteUnit in shardingRouteUnits) var routeMap = routeMaps[dataSourceName];
if (!routeMap.ContainsKey(shardingEntity))
{ {
routeMaps[shardingEntity].Add(shardingRouteUnit); routeMap.Add(shardingEntity, new HashSet<ShardingRouteUnit>() { shardingRouteUnit });
}
else
{
routeMap[shardingEntity].Add(shardingRouteUnit);
}
} }
} }
} }
return routeMaps.Select(o => o.Value).Cartesian().Select(o => new TableRouteResult(o,_shardingDatabaseProvider.GetShardingDbContextType())); //相同的数据源进行笛卡尔积
//[[ds0,01,a],[ds0,02,a],[ds1,01,a]],[[ds0,01,b],[ds0,03,b],[ds1,01,b]]
//=>
//[ds0,[{01,a},{01,b}]],[ds0,[{01,a},{03,b}]],[ds0,[{02,a},{01,b}]],[ds0,[{02,a},{03,b}]],[ds1,[{01,a},{01,b}]]
//如果笛卡尔积
var sqlRouteUnits = new List<ISqlRouteUnit>(31);
int dataSourceCount = 0;
bool isCrossTable = false;
bool existCrossTableTails = false;
foreach (var dataSourceName in tableRouteRuleContext.DataSourceRouteResult.IntersectDataSources)
{
if (routeMaps.ContainsKey(dataSourceName))
{
var routeMap = routeMaps[dataSourceName];
var tableRouteResults = routeMap.Select(o => o.Value).Cartesian()
.Select(o => new TableRouteResult(o.ToList())).Where(o=>!o.IsEmpty).ToList();
if (tableRouteResults.IsNotEmpty())
{
dataSourceCount++;
foreach (var tableRouteResult in tableRouteResults)
{
if (tableRouteResult.ReplaceTables.Count > 1)
{
isCrossTable = true;
if (tableRouteResult.HasDifferentTail)
{
existCrossTableTails = true;
}
}
sqlRouteUnits.Add(new SqlRouteUnit(dataSourceName, tableRouteResult));
}
}
}
}
return new ShardingRouteResult(sqlRouteUnits, sqlRouteUnits.Count == 0, dataSourceCount > 1, isCrossTable,
existCrossTableTails);
//
// var sqlRouteUnits = tableRouteRuleContext.DataSourceRouteResult.IntersectDataSources.SelectMany(
// dataSourceName =>
// {
// return routeMaps.Select(o => o.Value.Where(route => route.DataSourceName == dataSourceName))
// .Cartesian()
// .Select(o => (ISqlRouteUnit)new SqlRouteUnit(dataSourceName, new TableRouteResult(o.ToList())))
// .ToArray();
// }).Where(o => o.TableRouteResult.ReplaceTables.Any()).ToArray();
// return sqlRouteUnits;
// return routeMaps.Select(o => o.Value).Cartesian().Where(o=>o).Select(o => new TableRouteResult(o,_shardingDatabaseProvider.GetShardingDbContextType()));
} }
} }
} }

View File

@ -37,13 +37,13 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
{ {
return new TableRouteRuleContext(dataSourceRouteResult,queryable,queryEntities); return new TableRouteRuleContext(dataSourceRouteResult,queryable,queryEntities);
} }
public ISqlRouteUnit[] Route(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities) public ShardingRouteResult Route(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable, Dictionary<Type, IQueryable> queryEntities)
{ {
var ruleContext = CreateContext(dataSourceRouteResult,queryable, queryEntities); var ruleContext = CreateContext(dataSourceRouteResult,queryable, queryEntities);
return Route(ruleContext); return Route(ruleContext);
} }
private ISqlRouteUnit[] Route(TableRouteRuleContext ruleContext) private ShardingRouteResult Route(TableRouteRuleContext ruleContext)
{ {
return _tableRouteRuleEngine.Route(ruleContext); return _tableRouteRuleEngine.Route(ruleContext);
} }

View File

@ -7,7 +7,7 @@ using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
namespace ShardingCore.Sharding.MergeEngines.Common.Abstractions namespace ShardingCore.Sharding.MergeEngines.Common.Abstractions
{ {
internal interface ISqlRouteUnit public interface ISqlRouteUnit
{ {
string DataSourceName { get; } string DataSourceName { get; }
TableRouteResult TableRouteResult { get; } TableRouteResult TableRouteResult { get; }

View File

@ -8,7 +8,7 @@ using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
namespace ShardingCore.Sharding.MergeEngines.Common namespace ShardingCore.Sharding.MergeEngines.Common
{ {
internal class SqlRouteUnit: ISqlRouteUnit public class SqlRouteUnit: ISqlRouteUnit
{ {
public SqlRouteUnit(string dataSourceName, TableRouteResult tableRouteResult) public SqlRouteUnit(string dataSourceName, TableRouteResult tableRouteResult)
@ -19,5 +19,9 @@ namespace ShardingCore.Sharding.MergeEngines.Common
public string DataSourceName { get; } public string DataSourceName { get; }
public TableRouteResult TableRouteResult { get; } public TableRouteResult TableRouteResult { get; }
public override string ToString()
{
return $"{nameof(DataSourceName)}:{DataSourceName},{nameof(TableRouteResult)}:{TableRouteResult}";
}
} }
} }

View File

@ -8,11 +8,13 @@ using Microsoft.EntityFrameworkCore;
using ShardingCore.Core; using ShardingCore.Core;
using ShardingCore.Core.EntityMetadatas; using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources; using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine; using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions; using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine; using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.Extensions; using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
using ShardingCore.Sharding.ParallelTables; using ShardingCore.Sharding.ParallelTables;
using ShardingCore.Sharding.ShardingExecutors.Abstractions; using ShardingCore.Sharding.ShardingExecutors.Abstractions;
using ShardingCore.Sharding.ShardingExecutors.QueryableCombines; using ShardingCore.Sharding.ShardingExecutors.QueryableCombines;
@ -26,8 +28,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
private readonly IShardingRuntimeContext _shardingRuntimeContext; private readonly IShardingRuntimeContext _shardingRuntimeContext;
private readonly IQueryCompilerContext _queryCompilerContext; private readonly IQueryCompilerContext _queryCompilerContext;
private readonly QueryCombineResult _queryCombineResult; private readonly QueryCombineResult _queryCombineResult;
private readonly DataSourceRouteResult _dataSourceRouteResult; private readonly ShardingRouteResult _shardingRouteResult;
private readonly TableRouteResult[] _tableRouteResults;
/// <summary> /// <summary>
/// 本次查询跨库 /// 本次查询跨库
@ -46,39 +47,39 @@ namespace ShardingCore.Sharding.ShardingExecutors
private QueryCompilerExecutor _queryCompilerExecutor; private QueryCompilerExecutor _queryCompilerExecutor;
private bool? hasQueryCompilerExecutor; private bool? hasQueryCompilerExecutor;
private MergeQueryCompilerContext(IShardingRuntimeContext shardingRuntimeContext,IQueryCompilerContext queryCompilerContext, QueryCombineResult queryCombineResult, DataSourceRouteResult dataSourceRouteResult, IEnumerable<TableRouteResult> tableRouteResults) private MergeQueryCompilerContext(IShardingRuntimeContext shardingRuntimeContext,IQueryCompilerContext queryCompilerContext, QueryCombineResult queryCombineResult, ShardingRouteResult shardingRouteResult)
{ {
_shardingRuntimeContext = shardingRuntimeContext; _shardingRuntimeContext = shardingRuntimeContext;
_queryCompilerContext = queryCompilerContext; _queryCompilerContext = queryCompilerContext;
_queryCombineResult = queryCombineResult; _queryCombineResult = queryCombineResult;
_shardingRouteResult = shardingRouteResult;
_parallelTableManager = _shardingRuntimeContext.GetParallelTableManager(); _parallelTableManager = _shardingRuntimeContext.GetParallelTableManager();
_dataSourceRouteResult = dataSourceRouteResult; // _tableRouteResults = GetTableRouteResults(sqlRouteUnits).ToArray();
_tableRouteResults = GetTableRouteResults(tableRouteResults).ToArray(); _isCrossDataSource = shardingRouteResult.IsCrossDataSource;
_isCrossDataSource = dataSourceRouteResult.IntersectDataSources.Count > 1; _isCrossTable = shardingRouteResult.IsCrossTable;
_isCrossTable = _tableRouteResults.Count() > 1; _existCrossTableTails = shardingRouteResult.ExistCrossTableTails;
_existCrossTableTails = _tableRouteResults.Any(o => o.HasDifferentTail);
} }
//
// private IEnumerable<TableRouteResult> GetTableRouteResults(IEnumerable<TableRouteResult> tableRouteResults)
// {
// var routeResults = tableRouteResults as TableRouteResult[] ?? tableRouteResults.ToArray();
// if (_queryCompilerContext.GetQueryEntities().Count > 1&& routeResults.Length>0)
// {
// var entityMetadataManager = _queryCompilerContext.GetEntityMetadataManager();
// var queryShardingTables = _queryCompilerContext.GetQueryEntities().Keys.Where(o => entityMetadataManager.IsShardingTable(o)).ToArray();
// if (queryShardingTables.Length > 1 && _parallelTableManager.IsParallelTableQuery(queryShardingTables))
// {
// return routeResults.Where(o => o.ReplaceTables.Select(p => p.Tail).ToHashSet().Count == 1);
// }
// }
// return routeResults;
// }
private IEnumerable<TableRouteResult> GetTableRouteResults(IEnumerable<TableRouteResult> tableRouteResults) public static MergeQueryCompilerContext Create(IQueryCompilerContext queryCompilerContext, QueryCombineResult queryCombineResult, ShardingRouteResult shardingRouteResult)
{
var routeResults = tableRouteResults as TableRouteResult[] ?? tableRouteResults.ToArray();
if (_queryCompilerContext.GetQueryEntities().Count > 1&& routeResults.Length>0)
{
var entityMetadataManager = _queryCompilerContext.GetEntityMetadataManager();
var queryShardingTables = _queryCompilerContext.GetQueryEntities().Keys.Where(o => entityMetadataManager.IsShardingTable(o)).ToArray();
if (queryShardingTables.Length > 1 && _parallelTableManager.IsParallelTableQuery(queryShardingTables))
{
return routeResults.Where(o => o.ReplaceTables.Select(p => p.Tail).ToHashSet().Count == 1);
}
}
return routeResults;
}
public static MergeQueryCompilerContext Create(IQueryCompilerContext queryCompilerContext, QueryCombineResult queryCombineResult, DataSourceRouteResult dataSourceRouteResult,IEnumerable<TableRouteResult> tableRouteResults)
{ {
var shardingDbContext = queryCompilerContext.GetShardingDbContext(); var shardingDbContext = queryCompilerContext.GetShardingDbContext();
var shardingRuntimeContext = ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>(); var shardingRuntimeContext = ((DbContext)shardingDbContext).GetRequireService<IShardingRuntimeContext>();
return new MergeQueryCompilerContext(shardingRuntimeContext,queryCompilerContext, queryCombineResult,dataSourceRouteResult, tableRouteResults); return new MergeQueryCompilerContext(shardingRuntimeContext,queryCompilerContext, queryCombineResult,shardingRouteResult);
} }
public Dictionary<Type,IQueryable> GetQueryEntities() public Dictionary<Type,IQueryable> GetQueryEntities()
{ {
@ -149,7 +150,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
{ {
if (!hasQueryCompilerExecutor.HasValue) if (!hasQueryCompilerExecutor.HasValue)
{ {
if (_dataSourceRouteResult.IntersectDataSources.IsEmpty() || _tableRouteResults.IsEmpty()) if(_shardingRouteResult.IsEmpty)
{ {
hasQueryCompilerExecutor = false; hasQueryCompilerExecutor = false;
} }
@ -190,7 +191,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
/// <returns></returns> /// <returns></returns>
private bool IsSingleQuery() private bool IsSingleQuery()
{ {
return !_isCrossDataSource&&!_isCrossTable; return _shardingRouteResult.RouteUnits.Count==1;//&& !_isCrossDataSource&&!_isCrossTable;
} }
public bool IsCrossTable() public bool IsCrossTable()

View File

@ -18,6 +18,9 @@ namespace ShardingCore.Sharding.ShardingExecutors
{ {
public class QueryCompilerContextFactory : IQueryCompilerContextFactory public class QueryCompilerContextFactory : IQueryCompilerContextFactory
{ {
private readonly IDataSourceRouteRuleEngineFactory _dataSourceRouteRuleEngineFactory;
private readonly ITableRouteRuleEngineFactory _tableRouteRuleEngineFactory;
private static readonly ILogger<QueryCompilerContextFactory> _logger = private static readonly ILogger<QueryCompilerContextFactory> _logger =
InternalLoggerFactory.CreateLogger<QueryCompilerContextFactory>(); InternalLoggerFactory.CreateLogger<QueryCompilerContextFactory>();
private static readonly IQueryableCombine _enumerableQueryableCombine; private static readonly IQueryableCombine _enumerableQueryableCombine;
@ -35,9 +38,15 @@ namespace ShardingCore.Sharding.ShardingExecutors
_whereQueryableCombine = new WhereQueryableCombine(); _whereQueryableCombine = new WhereQueryableCombine();
} }
public QueryCompilerContextFactory(IDataSourceRouteRuleEngineFactory dataSourceRouteRuleEngineFactory,ITableRouteRuleEngineFactory tableRouteRuleEngineFactory)
{
_dataSourceRouteRuleEngineFactory = dataSourceRouteRuleEngineFactory;
_tableRouteRuleEngineFactory = tableRouteRuleEngineFactory;
}
public IQueryCompilerContext Create(IPrepareParseResult prepareParseResult) public IQueryCompilerContext Create(IPrepareParseResult prepareParseResult)
{ {
var logDebug = _logger.IsEnabled(LogLevel.Debug);
var queryCompilerContext = var queryCompilerContext =
QueryCompilerContext.Create(prepareParseResult); QueryCompilerContext.Create(prepareParseResult);
if (queryCompilerContext.GetQueryCompilerExecutor() is not null) if (queryCompilerContext.GetQueryCompilerExecutor() is not null)
@ -48,17 +57,17 @@ namespace ShardingCore.Sharding.ShardingExecutors
var queryableCombine = GetQueryableCombine(queryCompilerContext); var queryableCombine = GetQueryableCombine(queryCompilerContext);
_logger.LogDebug($"queryable combine:{queryableCombine.GetType()}"); _logger.LogDebug($"queryable combine:{queryableCombine.GetType()}");
var dataSourceRouteRuleEngineFactory = (IDataSourceRouteRuleEngineFactory)ShardingRuntimeContext.GetInstance().GetService(typeof(IDataSourceRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
var tableRouteRuleEngineFactory = (ITableRouteRuleEngineFactory)ShardingRuntimeContext.GetInstance().GetService(typeof(ITableRouteRuleEngineFactory<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType()));
_logger.LogLazyDebug(() => $"queryable combine before:{queryCompilerContext.GetQueryExpression().ShardingPrint()}"); _logger.LogLazyDebug(() => $"queryable combine before:{queryCompilerContext.GetQueryExpression().ShardingPrint()}");
var queryCombineResult = queryableCombine.Combine(queryCompilerContext); var queryCombineResult = queryableCombine.Combine(queryCompilerContext);
_logger.LogLazyDebug(() => $"queryable combine after:{queryCombineResult.GetCombineQueryable().ShardingPrint()}"); _logger.LogLazyDebug(() => $"queryable combine after:{queryCombineResult.GetCombineQueryable().ShardingPrint()}");
var dataSourceRouteResult = dataSourceRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable(), prepareParseResult.GetShardingDbContext(), prepareParseResult.GetQueryEntities()); var dataSourceRouteResult = _dataSourceRouteRuleEngineFactory.Route(queryCombineResult.GetCombineQueryable(), prepareParseResult.GetShardingDbContext(), prepareParseResult.GetQueryEntities());
_logger.LogLazyDebug(() => $"{dataSourceRouteResult}"); _logger.LogLazyDebug(() => $"{dataSourceRouteResult}");
var routeResults = tableRouteRuleEngineFactory.Route(dataSourceRouteResult,queryCombineResult.GetCombineQueryable(), prepareParseResult.GetQueryEntities()).ToArray(); var shardingRouteResult = _tableRouteRuleEngineFactory.Route(dataSourceRouteResult,queryCombineResult.GetCombineQueryable(), prepareParseResult.GetQueryEntities());
_logger.LogLazyDebug(() => $"table route results:{string.Join(","+Environment.NewLine,routeResults.Select(o=>o.GetPrintInfo()))}"); if (logDebug)
var mergeCombineCompilerContext = MergeQueryCompilerContext.Create(queryCompilerContext, queryCombineResult, dataSourceRouteResult, {
routeResults); _logger.LogDebug($"table route results:{shardingRouteResult}");
}
var mergeCombineCompilerContext = MergeQueryCompilerContext.Create(queryCompilerContext, queryCombineResult, sqlRouteUnits);
return mergeCombineCompilerContext; return mergeCombineCompilerContext;
} }