添加shardingrouteresult
This commit is contained in:
parent
3b4da3a7ef
commit
e8596eabdc
|
@ -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);
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,6 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
|
|
||||||
public interface ITableRouteRuleEngine
|
public interface ITableRouteRuleEngine
|
||||||
{
|
{
|
||||||
ShardingRouteUnit[] Route(TableRouteRuleContext tableRouteRuleContext);
|
ShardingRouteResult Route(TableRouteRuleContext tableRouteRuleContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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))}])";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue