优化分片查询吞吐量

This commit is contained in:
xuejiaming 2022-07-26 10:15:19 +08:00
parent ace2d0cb6c
commit 4ac8601583
17 changed files with 275 additions and 53 deletions

View File

@ -0,0 +1,133 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
{
internal class OneAtMostElementStreamMergeAsyncEnumerator<T> : IStreamMergeAsyncEnumerator<T>
{
private List<T>.Enumerator _enumerator;
private bool skip;
public OneAtMostElementStreamMergeAsyncEnumerator(IStreamMergeAsyncEnumerator<T> streamMergeAsyncEnumerator)
{
var list = new List<T>();
if (streamMergeAsyncEnumerator.HasElement())
{
list.Add(streamMergeAsyncEnumerator.ReallyCurrent);
}
_enumerator = list.GetEnumerator();
_enumerator.MoveNext();
skip = true;
}
#if !EFCORE2&&!EFCORE3&&!EFCORE5
public ValueTask DisposeAsync()
{
_enumerator.Dispose();
return ValueTask.CompletedTask;
}
public ValueTask<bool> MoveNextAsync()
{
var moveNext = _enumerator.MoveNext();
return ValueTask.FromResult<bool>(moveNext);
}
public void Dispose()
{
_enumerator.Dispose();
}
#endif
#if EFCORE3 || EFCORE5
public ValueTask DisposeAsync()
{
_enumerator.Dispose();
return new ValueTask();
}
public ValueTask<bool> MoveNextAsync()
{
var moveNext = _enumerator.MoveNext();
return new ValueTask<bool>(moveNext);
}
public void Dispose()
{
_enumerator.Dispose();
}
#endif
public bool MoveNext()
{
if (skip)
{
skip = false;
return null != _enumerator.Current;
}
var moveNext = _enumerator.MoveNext();
return moveNext;
}
public bool SkipFirst()
{
if (skip)
{
skip = false;
return true;
}
return false;
}
public bool HasElement()
{
return null != _enumerator.Current;
}
public void Reset()
{
throw new NotImplementedException();
}
object IEnumerator.Current => Current;
public T Current => GetCurrent();
public T ReallyCurrent => GetReallyCurrent();
public T GetCurrent()
{
if (skip)
return default;
return _enumerator.Current;
}
public T GetReallyCurrent()
{
return _enumerator.Current;
}
#if EFCORE2
public void Dispose()
{
_enumerator.Dispose();
}
public Task<bool> MoveNext(CancellationToken cancellationToken = new CancellationToken())
{
if (skip)
{
skip = false;
return Task.FromResult(null != _enumerator.Current);
}
var moveNext = _enumerator.MoveNext();
return Task.FromResult(moveNext);
}
#endif
}
}

View File

@ -20,7 +20,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines.Enumer
protected override IExecutor<IStreamMergeAsyncEnumerator<TEntity>> CreateExecutor0(bool async)
{
GetStreamMergeContext().ReSetTake(1);
GetStreamMergeContext().ReSetTake(2);
return new DefaultEnumeratorExecutor<TEntity>(GetStreamMergeContext(), GetStreamMergeCombine(), async);
}
}

View File

@ -36,7 +36,7 @@ namespace ShardingCore.Sharding.MergeEngines.EnumeratorStreamMergeEngines.Enumer
var streamMergeContext = GetStreamMergeContext();
var shardingRouteResult = streamMergeContext.ShardingRouteResult;
var sqlRouteUnit = shardingRouteResult.RouteUnits.First();
var shardingDbContext = streamMergeContext.CreateDbContext(sqlRouteUnit, ConnectionModeEnum.MEMORY_STRICTLY);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlRouteUnit);
var newQueryable = (IQueryable<TEntity>)streamMergeContext.GetOriginalQueryable().ReplaceDbContextQueryable(shardingDbContext);
var enumeratorParallelExecutor = new SingleQueryEnumeratorExecutor<TEntity>(streamMergeContext);
if (async)

View File

@ -13,6 +13,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
internal abstract class AbstractExecutor<TResult> : IExecutor<TResult>
{
private readonly StreamMergeContext _streamMergeContext;
/// <summary>
/// not cancelled const mark
/// </summary>
@ -22,10 +23,11 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
/// cancelled const mark
/// </summary>
private const int cancelled = 0;
/// <summary>
/// cancel status
/// </summary>
private int cancelStatus= notCancelled;
private int cancelStatus = notCancelled;
protected AbstractExecutor(StreamMergeContext streamMergeContext)
{
@ -36,6 +38,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
{
return _streamMergeContext;
}
/// <summary>
/// 创建熔断器来中断符合查询的结果比如firstordefault只需要在顺序查询下查询到第一个
/// 如果不是顺序查询则需要所有表的第一个进行内存再次查询
@ -53,7 +56,9 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
return cancelStatus == cancelled;
}
public async Task<LinkedList<TResult>> ExecuteAsync(bool async, DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
public async Task<LinkedList<TResult>> ExecuteAsync(bool async,
DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit,
CancellationToken cancellationToken = new CancellationToken())
{
try
{
@ -65,8 +70,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
throw;
}
}
private async Task<LinkedList<TResult>> ExecuteAsync0(bool async, DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
private async Task<LinkedList<TResult>> ExecuteAsync0(bool async,
DataSourceSqlExecutorUnit dataSourceSqlExecutorUnit,
CancellationToken cancellationToken = new CancellationToken())
{
var streamMergeContext = GetStreamMergeContext();
var circuitBreaker = CreateCircuitBreaker();
var executorGroups = dataSourceSqlExecutorUnit.SqlExecutorGroups;
LinkedList<TResult> result = new LinkedList<TResult>();
@ -84,13 +93,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
var dbContexts = routeQueryResults.Select(o => o.DbContext);
foreach (var dbContext in dbContexts)
{
#if !EFCORE2
await dbContext.DisposeAsync();
#endif
#if EFCORE2
dbContext.Dispose();
#endif
await streamMergeContext.DbContextDisposeAsync(dbContext);
}
}
else
@ -105,20 +108,22 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
var hasNextLoop = executorGroupsCount > 0;
if (hasNextLoop)
{
if (IsCancelled()|| circuitBreaker.Terminated(result))
if (IsCancelled() || circuitBreaker.Terminated(result))
break;
}
}
return result;
}
/// <summary>
/// 同库同组下面的并行异步执行,需要归并成一个结果
/// </summary>
/// <param name="sqlExecutorUnits"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
protected async Task<LinkedList<ShardingMergeResult<TResult>>> GroupExecuteAsync(List<SqlExecutorUnit> sqlExecutorUnits, CancellationToken cancellationToken = new CancellationToken())
protected async Task<LinkedList<ShardingMergeResult<TResult>>> GroupExecuteAsync(
List<SqlExecutorUnit> sqlExecutorUnits, CancellationToken cancellationToken = new CancellationToken())
{
if (sqlExecutorUnits.Count <= 0)
{
@ -128,8 +133,9 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
{
var result = new LinkedList<ShardingMergeResult<TResult>>();
var tasks = sqlExecutorUnits.Select(sqlExecutorUnit => ExecuteUnitAsync(sqlExecutorUnit, cancellationToken)).ToArray();
var tasks = sqlExecutorUnits
.Select(sqlExecutorUnit => ExecuteUnitAsync(sqlExecutorUnit, cancellationToken)).ToArray();
var results = await TaskHelper.WhenAllFastFail(tasks);
foreach (var r in results)
{
@ -139,14 +145,17 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Abstractions
return result;
}
}
protected virtual void MergeParallelExecuteResult(LinkedList<TResult> previewResults, IEnumerable<TResult> parallelResults, bool async)
protected virtual void MergeParallelExecuteResult(LinkedList<TResult> previewResults,
IEnumerable<TResult> parallelResults, bool async)
{
foreach (var parallelResult in parallelResults)
{
previewResults.AddLast(parallelResult);
}
}
protected abstract Task<ShardingMergeResult<TResult>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit,
CancellationToken cancellationToken = new CancellationToken());
}
}
}

View File

@ -5,13 +5,16 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core;
using ShardingCore.Exceptions;
using ShardingCore.Sharding.Enumerators;
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
using ShardingCore.Sharding.Enumerators.StreamMergeAsync.EFCore2x;
using ShardingCore.Sharding.MergeEngines.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common;
using ShardingCore.Sharding.MergeEngines.Executors.Abstractions;
using ShardingCore.Sharding.MergeEngines.Executors.CircuitBreakers;
using ShardingCore.Sharding.ShardingExecutors;
#if EFCORE2
using Microsoft.EntityFrameworkCore.Extensions.Internal;
@ -140,5 +143,62 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators.Abstractions
enumator.MoveNext();
return enumator;
}
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var shardingMergeResult = await ExecuteUnitAsync0(sqlExecutorUnit, cancellationToken);
var dbContext = shardingMergeResult.DbContext;
var streamMergeAsyncEnumerator = shardingMergeResult.MergeResult;
//连接数严格的会在内存中聚合然后聚合后回收,非连接数严格需要判断是否需要当前执行单元直接回收
//first last 等操作没有skip就可以回收如果没有元素就可以回收
//single如果没有元素就可以回收
//enumerable如果没有元素就可以回收
if (sqlExecutorUnit.ConnectionMode != ConnectionModeEnum.CONNECTION_STRICTLY)
{
var streamMergeContext = GetStreamMergeContext();
if (DisposeInExecuteUnit(streamMergeContext,streamMergeAsyncEnumerator))
{
var disConnectionStreamMergeAsyncEnumerator = new OneAtMostElementStreamMergeAsyncEnumerator<TResult>(streamMergeAsyncEnumerator);
await streamMergeContext.DbContextDisposeAsync(dbContext);
return new ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>(null,
disConnectionStreamMergeAsyncEnumerator);
}
}
return shardingMergeResult;
}
/// <summary>
/// 是否需要在执行单元中直接回收掉链接有助于提高吞吐量
/// </summary>
/// <param name="streamMergeContext"></param>
/// <param name="streamMergeAsyncEnumerator"></param>
/// <returns></returns>
private bool DisposeInExecuteUnit(StreamMergeContext streamMergeContext,IStreamMergeAsyncEnumerator<TResult> streamMergeAsyncEnumerator)
{
var queryMethodName = streamMergeContext.MergeQueryCompilerContext.GetQueryMethodName();
var hasElement = streamMergeAsyncEnumerator.HasElement();
switch (queryMethodName)
{
case nameof(Queryable.First):
case nameof(Queryable.FirstOrDefault):
case nameof(Queryable.Last):
case nameof(Queryable.LastOrDefault):
{
var skip = streamMergeContext.GetSkip();
return skip is null or < 0||!hasElement;
}
case nameof(Queryable.Single):
case nameof(Queryable.SingleOrDefault):
case QueryCompilerContext.ENUMERABLE:
{
return !hasElement;
}
}
return false;
}
protected abstract Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(
SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken());
}
}

View File

@ -32,13 +32,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
_async = async;
}
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var streamMergeContext = GetStreamMergeContext();
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var sqlSequenceRouteUnit = sqlExecutorUnit.RouteUnit.As<SqlSequenceRouteUnit>();
var sequenceResult = sqlSequenceRouteUnit.SequenceResult;
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit, connectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit);
var newQueryable = _noPaginationQueryable
.Skip(sequenceResult.Skip)
.Take(sequenceResult.Take)

View File

@ -44,12 +44,10 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
return base.CombineInMemoryStreamMergeAsyncEnumerator(streamsAsyncEnumerators);
}
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var streamMergeContext = GetStreamMergeContext();
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit);
var newQueryable = (IQueryable<TResult>)streamMergeContext.GetReWriteQueryable()
.ReplaceDbContextQueryable(shardingDbContext);

View File

@ -28,11 +28,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
_async = async;
}
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}
protected override IStreamMergeCombine GetStreamMergeCombine()
{
return _streamMergeCombine;

View File

@ -36,12 +36,11 @@ internal class LastOrDefaultEnumeratorExecutor<TResult> : AbstractEnumeratorExec
return base.CombineInMemoryStreamMergeAsyncEnumerator(streamsAsyncEnumerators);
}
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var streamMergeContext = GetStreamMergeContext();
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit);
var newQueryable = (IQueryable<TResult>)_queryable.ReplaceDbContextQueryable(shardingDbContext);
var streamMergeAsyncEnumerator = await AsyncParallelEnumerator(newQueryable, _async, cancellationToken);

View File

@ -33,12 +33,11 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
_async = async;
}
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var streamMergeContext = GetStreamMergeContext();
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlExecutorUnit.RouteUnit);
var newQueryable = _reverseOrderQueryable
.ReplaceDbContextQueryable(shardingDbContext).As<IQueryable<TResult>>();
var streamMergeAsyncEnumerator = await AsyncParallelEnumerator(newQueryable, _async, cancellationToken);

View File

@ -32,13 +32,12 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
_noPaginationQueryable = streamMergeContext.GetOriginalQueryable().RemoveSkip().RemoveTake().As<IQueryable<TResult>>();
}
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override async Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var streamMergeContext = GetStreamMergeContext();
var connectionMode = streamMergeContext.RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var sqlSequenceRouteUnit = sqlExecutorUnit.RouteUnit.As<SqlSequenceRouteUnit>();
var sequenceResult = sqlSequenceRouteUnit.SequenceResult;
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit, connectionMode);
var shardingDbContext = streamMergeContext.CreateDbContext(sqlSequenceRouteUnit);
var newQueryable = _noPaginationQueryable
.Skip(sequenceResult.Skip)
.Take(sequenceResult.Take)

View File

@ -22,7 +22,7 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Enumerators
public SingleQueryEnumeratorExecutor(StreamMergeContext streamMergeContext) : base(streamMergeContext)
{
}
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
protected override Task<ShardingMergeResult<IStreamMergeAsyncEnumerator<TResult>>> ExecuteUnitAsync0(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
throw new NotImplementedException();
}

View File

@ -26,11 +26,10 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Methods.Abstractions
protected override async Task<ShardingMergeResult<RouteQueryResult<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var connectionMode = GetStreamMergeContext().RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var dataSourceName = sqlExecutorUnit.RouteUnit.DataSourceName;
var routeResult = sqlExecutorUnit.RouteUnit.TableRouteResult;
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit);
var newQueryable = GetStreamMergeContext().GetReWriteQueryable()
.ReplaceDbContextQueryable(shardingDbContext);

View File

@ -26,11 +26,10 @@ namespace ShardingCore.Sharding.MergeEngines.Executors.Methods.Abstractions
protected override async Task<ShardingMergeResult<RouteQueryResult<TResult>>> ExecuteUnitAsync(SqlExecutorUnit sqlExecutorUnit, CancellationToken cancellationToken = new CancellationToken())
{
var connectionMode = GetStreamMergeContext().RealConnectionMode(sqlExecutorUnit.ConnectionMode);
var dataSourceName = sqlExecutorUnit.RouteUnit.DataSourceName;
var routeResult = sqlExecutorUnit.RouteUnit.TableRouteResult;
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit, connectionMode);
var shardingDbContext = GetStreamMergeContext().CreateDbContext(sqlExecutorUnit.RouteUnit);
var newQueryable = GetStreamMergeContext().GetReWriteQueryable()
.ReplaceDbContextQueryable(shardingDbContext);

View File

@ -171,8 +171,11 @@ namespace ShardingCore.Sharding.ShardingExecutors
public QueryCompilerExecutor GetQueryCompilerExecutor()
{
//只获取第一次所以判断是否已经获取过了
if (!hasQueryCompilerExecutor.HasValue)
{
//空结果
//todo 后续优化直接无需后续的解析之类的
if(_shardingRouteResult.IsEmpty)
{
hasQueryCompilerExecutor = false;

View File

@ -22,8 +22,10 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using ShardingCore.Core.RuntimeContexts;
using ShardingCore.Core.ShardingConfigurations;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Sharding.Enumerators;
using ShardingCore.Sharding.MergeEngines.Abstractions;
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
using ShardingCore.Sharding.ShardingExecutors;
namespace ShardingCore.Sharding
@ -98,7 +100,7 @@ namespace ShardingCore.Sharding
_trackerManager = ShardingRuntimeContext.GetTrackerManager();
_shardingConfigOptions = ShardingRuntimeContext.GetShardingConfigOptions();
QueryEntities = MergeQueryCompilerContext.GetQueryEntities().Keys.ToHashSet();
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>();
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>(Environment.ProcessorCount,mergeQueryCompilerContext.GetShardingRouteResult().RouteUnits.Count);
Orders = parseResult.GetOrderByContext().PropertyOrders.ToArray();
Skip = parseResult.GetPaginationContext().Skip;
Take = parseResult.GetPaginationContext().Take;
@ -123,21 +125,13 @@ namespace ShardingCore.Sharding
/// 创建对应的dbcontext
/// </summary>
/// <param name="sqlRouteUnit">数据库路由最小单元</param>
/// <param name="connectionMode"></param>
/// <returns></returns>
public DbContext CreateDbContext(ISqlRouteUnit sqlRouteUnit, ConnectionModeEnum connectionMode)
public DbContext CreateDbContext(ISqlRouteUnit sqlRouteUnit)
{
var routeTail = _routeTailFactory.Create(sqlRouteUnit.TableRouteResult);
//如果开启了读写分离或者本次查询是跨表的表示本次查询的dbcontext是不存储的用完后就直接dispose
var parallelQuery = IsParallelQuery();
var strategy = !parallelQuery
? CreateDbContextStrategyEnum.ShareConnection
: CreateDbContextStrategyEnum.IndependentConnectionQuery;
var dbContext = GetShardingDbContext().GetDbContext(sqlRouteUnit.DataSourceName, strategy, routeTail);
if (parallelQuery && RealConnectionMode(connectionMode) == ConnectionModeEnum.MEMORY_STRICTLY)
{
_parallelDbContexts.TryAdd(dbContext, null);
}
var dbContext = GetShardingDbContext().GetDbContext(sqlRouteUnit.DataSourceName, CreateDbContextStrategyEnum.IndependentConnectionQuery, routeTail);
_parallelDbContexts.TryAdd(dbContext, null);
return dbContext;
}
@ -402,5 +396,32 @@ namespace ShardingCore.Sharding
ReSetOrders(propertyOrders);
}
}
#if !EFCORE2
public async ValueTask<bool> DbContextDisposeAsync(DbContext dbContext)
{
if (_parallelDbContexts.TryRemove(dbContext, out var _))
{
await dbContext.DisposeAsync();
return true;
}
return false;
}
#endif
#if EFCORE2
public Task<bool> DbContextDisposeAsync(DbContext dbContext)
{
if (_parallelDbContexts.TryRemove(dbContext, out var _))
{
dbContext.Dispose();
return Task.FromResult(true);
}
return Task.FromResult(false);
}
#endif
}
}

View File

@ -34,6 +34,9 @@
<Compile Update="..\..\src\ShardingCore\Sharding\ShardingExecutors\CustomerQueryScope.cs">
<Link>Sharding\ShardingExecutors\CustomerQueryScope.cs</Link>
</Compile>
<Compile Update="..\..\src\ShardingCore\Sharding\MergeEngines\Executors\Enumerators\FirstOrDefaultEnumeratorExecutor.cs">
<Link>Sharding\MergeEngines\Executors\Enumerators\FirstOrDefaultEnumeratorExecutor.cs</Link>
</Compile>
</ItemGroup>