优化自动追踪如果不跨表将和普通efcore一样

This commit is contained in:
xuejiaming 2021-09-29 22:52:43 +08:00
parent 6d2b565f5e
commit 093b649664
13 changed files with 118 additions and 46 deletions

View File

@ -39,7 +39,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.2x", "src2x\Sh
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.Test50_2x", "test\ShardingCore.Test50_2x\ShardingCore.Test50_2x.csproj", "{E4DAA43A-B64D-45CF-81B8-7B8FD338D686}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.SqlServerShardingDataSource", "samples\Sample.SqlServerShardingDataSource\Sample.SqlServerShardingDataSource.csproj", "{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.SqlServerShardingDataSource", "samples\Sample.SqlServerShardingDataSource\Sample.SqlServerShardingDataSource.csproj", "{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src5x", "src5x", "{EB1C9149-78C9-4D99-BE3F-B80FE2015E96}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardingCore.5x", "src5x\ShardingCore.5x\ShardingCore.5x.csproj", "{68A9F118-EF0A-4D03-8845-77D084561A28}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -103,6 +107,10 @@ Global
{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF}.Release|Any CPU.Build.0 = Release|Any CPU
{68A9F118-EF0A-4D03-8845-77D084561A28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{68A9F118-EF0A-4D03-8845-77D084561A28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{68A9F118-EF0A-4D03-8845-77D084561A28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{68A9F118-EF0A-4D03-8845-77D084561A28}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -122,6 +130,7 @@ Global
{A07C597D-339D-4378-BE4C-A2AF7473340B} = {F91949B0-02D5-4E3B-ACF4-AFA6C99A1E04}
{E4DAA43A-B64D-45CF-81B8-7B8FD338D686} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
{68A9F118-EF0A-4D03-8845-77D084561A28} = {EB1C9149-78C9-4D99-BE3F-B80FE2015E96}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291}

View File

@ -13,26 +13,6 @@ namespace ShardingCore.Extensions
*/
public static class StreamMergeContextExtension
{
/// <summary>
/// 本次查询是否涉及到分表
/// </summary>
/// <param name="streamMergeContext"></param>
/// <typeparam name="TEntity"></typeparam>
/// <returns></returns>
public static bool IsNormalQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
{
return streamMergeContext.QueryEntities.Any(o=>!o.IsShardingDataSource()&&!o.IsShardingTable());
}
/// <summary>
/// 单路由查询
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="streamMergeContext"></param>
/// <returns></returns>
public static bool IsSingleRouteQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
{
return streamMergeContext.DataSourceRouteResult.IntersectDataSources.Count==1&&streamMergeContext.TableRouteResults.Count()==1;
}
/// <summary>
/// 单表查询
/// </summary>

View File

@ -11,8 +11,19 @@ namespace ShardingCore.Sharding.PaginationConfigurations.MultiQueryPagination
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
/// <summary>
/// 多次查询条件
/// </summary>
public interface IMultiQueryPredicate
{
public bool Continue(long total, int currentSkip, int tables);
/// <summary>
/// 是否继续执行多次查询
/// </summary>
/// <param name="total">总total</param>
/// <param name="stillNeedSkip">还需跳过数目</param>
/// <param name="realContexts">执行的sql具体条数(路由条数)</param>
/// <param name="alreadyExecuteTimes">已经执行了多少次了</param>
/// <returns></returns>
public bool Continue(long total, int stillNeedSkip, int realContexts,int alreadyExecuteTimes);
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ShardingCore.Sharding.PaginationConfigurations.MultiQueryPagination
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/29 17:26:06
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class SimpleMultiQueryPredicate : IMultiQueryPredicate
{
/// <summary>
/// 如果需要跳过得条数大于5000并且已经执行次数小于路有数最大5次的情况下继续执行多次查询
/// </summary>
/// <param name="total"></param>
/// <param name="stillNeedSkip"></param>
/// <param name="realContexts"></param>
/// <param name="alreadyExecuteTimes"></param>
/// <returns></returns>
public bool Continue(long total, int stillNeedSkip, int realContexts, int alreadyExecuteTimes)
{
if (stillNeedSkip > 5000)
{
if (alreadyExecuteTimes <= 5 && alreadyExecuteTimes <= realContexts)
{
return true;
}
}
return false;
}
}
}

View File

@ -4,6 +4,7 @@ using System.Linq.Expressions;
using System.Text;
using Microsoft.EntityFrameworkCore.Infrastructure;
using ShardingCore.Core;
using ShardingCore.Sharding.PaginationConfigurations.MultiQueryPagination;
namespace ShardingCore.Sharding.PaginationConfigurations
{
@ -58,8 +59,9 @@ namespace ShardingCore.Sharding.PaginationConfigurations
/// 启用多次查询排序
/// </summary>
/// <returns></returns>
public PaginationBuilder<TEntity> ConfigMultiQueryShardingPage()
public PaginationBuilder<TEntity> ConfigMultiQueryShardingPage(IMultiQueryPredicate multiQueryPredicate)
{
_metadata.MultiQueryPredicate = multiQueryPredicate;
return this;
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ShardingCore.Sharding.PaginationConfigurations.MultiQueryPagination;
namespace ShardingCore.Sharding.PaginationConfigurations
{
@ -49,5 +50,12 @@ namespace ShardingCore.Sharding.PaginationConfigurations
[Obsolete]
public bool EnableUnevenShardingPage => UnevenFactorGe > 0 && UnevenFactorGe < 1 && UnevenLimit > 0;
public IMultiQueryPredicate MultiQueryPredicate { get; set; }
/// <summary>
/// 是否启用多次查询
/// </summary>
public bool EnableMultiQuery => MultiQueryPredicate != null;
}
}

View File

@ -11,6 +11,9 @@ namespace ShardingCore.Sharding.PaginationConfigurations.ReversePagination
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
/// <summary>
/// 反向排序条件
/// </summary>
public interface IReverserPredicate
{
}

View File

@ -130,7 +130,10 @@ namespace ShardingCore.Sharding
if (!_dbContextCaches.TryGetValue(dataSourceName, out var tailDbContexts))
{
tailDbContexts = new ConcurrentDictionary<string, DbContext>();
_dbContextCaches.TryAdd(dataSourceName, tailDbContexts);
if(!_dbContextCaches.TryAdd(dataSourceName, tailDbContexts))
{
_dbContextCaches.TryGetValue(dataSourceName, out tailDbContexts);
}
}
var cacheKey = routeTail.GetRouteTailIdentity();
if (!tailDbContexts.TryGetValue(cacheKey, out var dbContext))

View File

@ -48,8 +48,8 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
public IEnumeratorStreamMergeEngine<TEntity> ExecuteAsync(CancellationToken cancellationToken = new CancellationToken())
{
cancellationToken.ThrowIfCancellationRequested();
//操作单表或者单分库分表之类的
if (_streamMergeContext.IsNormalQuery()||_streamMergeContext.IsSingleRouteQuery())
//本次查询没有跨库没有跨表就可以直接执行
if (!_streamMergeContext.IsCrossDataSource&&!_streamMergeContext.IsCrossTable)
{
return new SingleQueryEnumeratorAsyncStreamMergeEngine<TShardingDbContext, TEntity>(_streamMergeContext);
}
@ -76,15 +76,6 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
if (mergeEngine != null)
return mergeEngine;
//if (paginationMetadata.EnableUnevenShardingPage)
//{
// if (paginationMetadata.IsUseUneven(_shardingPageManager.Current.RouteQueryResults, _streamMergeContext.Skip.GetValueOrDefault()))
// {
// }
//}
}
}

View File

@ -44,7 +44,18 @@ namespace ShardingCore.Sharding
/// ±¾´Î²éѯÉæ¼°µÄ¶ÔÏó
/// </summary>
public ISet<Type> QueryEntities { get; }
/// <summary>
/// 本次查询是否包含notracking
/// </summary>
public bool? IsNoTracking { get; }
/// <summary>
/// 本次查询跨库
/// </summary>
public bool IsCrossDataSource { get; }
/// <summary>
/// 本次查询跨表
/// </summary>
public bool IsCrossTable { get; }
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,
DataSourceRouteResult dataSourceRouteResult,
@ -66,6 +77,8 @@ namespace ShardingCore.Sharding
QueryEntities = source.ParseQueryableRoute();
DataSourceRouteResult = dataSourceRouteResult;
TableRouteResults= tableRouteResults;
IsCrossDataSource = dataSourceRouteResult.IntersectDataSources.Count > 1;
IsCrossTable=tableRouteResults.Count() > 1;
//RouteResults = _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
}
//public StreamMergeContext(IQueryable<T> source,IEnumerable<TableRouteResult> routeResults,
@ -101,7 +114,7 @@ namespace ShardingCore.Sharding
public DbContext CreateDbContext(string dataSourceName, TableRouteResult tableRouteResult)
{
var routeTail = _routeTailFactory.Create(tableRouteResult);
return _shardingDbContext.GetDbContext(dataSourceName, true, routeTail);
return _shardingDbContext.GetDbContext(dataSourceName, IsCrossTable, routeTail);
}
public IRouteTail Create(TableRouteResult tableRouteResult)

View File

@ -26,11 +26,15 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
{
_trackerManager = ShardingContainer.GetService<ITrackerManager<TShardingDbContext>>();
}
/// <summary>
/// 手动追踪
/// </summary>
private bool IsUseManualTrack => GetIsUseManualTrack();
private bool IsUseTrack => GetIsUseTracker();
private bool GetIsUseTracker()
private bool GetIsUseManualTrack()
{
if (!GetStreamMergeContext().IsCrossTable)
return false;
if (GetStreamMergeContext().IsNoTracking.HasValue)
{
return !GetStreamMergeContext().IsNoTracking.Value;
@ -46,7 +50,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
var current = DoMergeResult<TResult>();
if (current != null)
{
if (IsUseTrack && _trackerManager.EntityUseTrack(current.GetType()))
if (IsUseManualTrack && _trackerManager.EntityUseTrack(current.GetType()))
{
var c = (object)current;
var genericDbContext = GetStreamMergeContext().GetShardingDbContext().CreateGenericDbContext(c);
@ -69,7 +73,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
var current = await DoMergeResultAsync<TResult>(cancellationToken);
if (current != null)
{
if (IsUseTrack && _trackerManager.EntityUseTrack(current.GetType()))
if (IsUseManualTrack && _trackerManager.EntityUseTrack(current.GetType()))
{
var c = (object)current;
var genericDbContext = GetStreamMergeContext().GetShardingDbContext().CreateGenericDbContext(c);

View File

@ -27,10 +27,12 @@ namespace ShardingCore.Sharding.StreamMergeEngines
_trackerManager = ShardingContainer.GetService<ITrackerManager<TShardingDbContext>>();
}
private bool IsUseTrack => GetIsUseTracker();
private bool IsUseManualTrack => GetIsUseManualTrack();
private bool GetIsUseTracker()
private bool GetIsUseManualTrack()
{
if (!_mergeContext.IsCrossTable)
return false;
if (_mergeContext.IsNoTracking.HasValue)
{
return !_mergeContext.IsNoTracking.Value;
@ -48,7 +50,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
var asyncEnumerator = new EnumeratorShardingQueryExecutor<TShardingDbContext,T>(_mergeContext).ExecuteAsync(cancellationToken)
.GetAsyncEnumerator(cancellationToken);
if (IsUseTrack&&_trackerManager.EntityUseTrack(typeof(T)))
if (IsUseManualTrack&&_trackerManager.EntityUseTrack(typeof(T)))
{
return new AsyncTrackerEnumerator<T>(_mergeContext, asyncEnumerator);
}
@ -62,7 +64,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
{
var asyncEnumerator = ((IAsyncEnumerable<T>)new EnumeratorShardingQueryExecutor<TShardingDbContext,T>(_mergeContext).ExecuteAsync())
.GetEnumerator();
if (IsUseTrack&&_trackerManager.EntityUseTrack(typeof(T)))
if (IsUseManualTrack&&_trackerManager.EntityUseTrack(typeof(T)))
{
return new AsyncTrackerEnumerator<T>(_mergeContext, asyncEnumerator);
}
@ -76,7 +78,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
var enumerator = ((IEnumerable<T>)new EnumeratorShardingQueryExecutor<TShardingDbContext,T>(_mergeContext).ExecuteAsync())
.GetEnumerator();
if (IsUseTrack&&_trackerManager.EntityUseTrack(typeof(T)))
if (IsUseManualTrack&&_trackerManager.EntityUseTrack(typeof(T)))
{
return new TrackerEnumerator<T>(_mergeContext, enumerator);
}

View File

@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RootNamespace>ShardingCore</RootNamespace>
<AssemblyName>ShardingCore</AssemblyName>
<Description>easy sharding for efcore 2.x 3.x 5.x 6.x lib.</Description>
</PropertyGroup>
</Project>