From 07fd59f2883c8aee6c577d419817f21784af317e Mon Sep 17 00:00:00 2001 From: xuejiaming <326308290@qq.com> Date: Fri, 31 Dec 2021 21:35:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81[#88]QueryFilter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DefaultDbContext.cs | 12 ++ .../MyDbContext.cs | 1 - src/ShardingCore/DIExtension.cs | 3 +- .../DefaultShardingTrackQueryExecutor.cs | 138 ++++++------------ .../INativeEnumeratorTrackQueryExecutor.cs | 15 -- ...ecutor.cs => INativeTrackQueryExecutor.cs} | 4 +- .../NativeEnumeratorTrackQueryExecutor.cs | 25 ---- ...xecutor.cs => NativeTrackQueryExecutor.cs} | 15 +- .../Visitors/QueryableRouteDiscoverVisitor.cs | 32 +++- test/ShardingCore.Test/ShardingTest.cs | 5 + test/ShardingCore.Test2x/ShardingTest.cs | 5 + test/ShardingCore.Test3x/ShardingTest.cs | 5 + test/ShardingCore.Test5x/ShardingTest.cs | 5 + 13 files changed, 122 insertions(+), 143 deletions(-) delete mode 100644 src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeEnumeratorTrackQueryExecutor.cs rename src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/{INativeSingleTrackQueryExecutor.cs => INativeTrackQueryExecutor.cs} (58%) delete mode 100644 src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeEnumeratorTrackQueryExecutor.cs rename src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/{NativeSingleTrackQueryExecutor.cs => NativeTrackQueryExecutor.cs} (67%) diff --git a/samples/Sample.NoShardingMultiLevel/DefaultDbContext.cs b/samples/Sample.NoShardingMultiLevel/DefaultDbContext.cs index bca54d63..d0bc28c2 100644 --- a/samples/Sample.NoShardingMultiLevel/DefaultDbContext.cs +++ b/samples/Sample.NoShardingMultiLevel/DefaultDbContext.cs @@ -17,5 +17,17 @@ namespace Sample.NoShardingMultiLevel modelBuilder.ApplyConfiguration(new CompanyMap()); modelBuilder.ApplyConfiguration(new DepartmentMap()); } + + public override void Dispose() + { + Console.WriteLine("DefaultDbContext dispose"); + base.Dispose(); + } + + public override ValueTask DisposeAsync() + { + Console.WriteLine("DefaultDbContext disposeasync"); + return base.DisposeAsync(); + } } } diff --git a/samples/Sample.SqlServerShardingTable/MyDbContext.cs b/samples/Sample.SqlServerShardingTable/MyDbContext.cs index 7f8afca0..43af8e4b 100644 --- a/samples/Sample.SqlServerShardingTable/MyDbContext.cs +++ b/samples/Sample.SqlServerShardingTable/MyDbContext.cs @@ -48,7 +48,6 @@ namespace Sample.SqlServerShardingTable entity.Property(o => o.Id).ValueGeneratedNever(); entity.Property(o=>o.Name).IsRequired().IsUnicode(false).HasMaxLength(50); entity.HasQueryFilter(o => o.IsDelete == false); - entity.HasQueryFilter(o => o.Name == "123"); entity.ToTable(nameof(MultiShardingOrder)); }); } diff --git a/src/ShardingCore/DIExtension.cs b/src/ShardingCore/DIExtension.cs index 2319f372..60a770aa 100644 --- a/src/ShardingCore/DIExtension.cs +++ b/src/ShardingCore/DIExtension.cs @@ -131,8 +131,7 @@ namespace ShardingCore services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(); + services.TryAddSingleton(); services.TryAddShardingJob(); return services; diff --git a/src/ShardingCore/Sharding/ShardingExecutors/DefaultShardingTrackQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingExecutors/DefaultShardingTrackQueryExecutor.cs index efbbc6de..c6604ca1 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/DefaultShardingTrackQueryExecutor.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/DefaultShardingTrackQueryExecutor.cs @@ -17,40 +17,42 @@ namespace ShardingCore.Sharding.ShardingExecutors { public class DefaultShardingTrackQueryExecutor: IShardingTrackQueryExecutor { - private static readonly MethodInfo NativeSingleTrackQueryExecutorTrack - = typeof(NativeSingleTrackQueryExecutor) + //对象查询追踪方法 + private static readonly MethodInfo Track + = typeof(NativeTrackQueryExecutor) .GetMethod( - nameof(NativeSingleTrackQueryExecutor.Track), + nameof(NativeTrackQueryExecutor.Track), BindingFlags.Instance | BindingFlags.Public ); - private static readonly MethodInfo NativeSingleTrackQueryExecutorTrackAsync - = typeof(NativeSingleTrackQueryExecutor) + //对象查询追踪方法 + private static readonly MethodInfo TrackAsync + = typeof(NativeTrackQueryExecutor) .GetMethod( - nameof(NativeSingleTrackQueryExecutor.TrackAsync), + nameof(NativeTrackQueryExecutor.TrackAsync), BindingFlags.Instance | BindingFlags.Public ); - private static readonly MethodInfo NativeEnumeratorTrackQueryExecutorTrack - = typeof(NativeEnumeratorTrackQueryExecutor) + //列表查询追踪方法 + private static readonly MethodInfo TrackEnumerable + = typeof(NativeTrackQueryExecutor) .GetMethod( - nameof(NativeEnumeratorTrackQueryExecutor.Track), + nameof(NativeTrackQueryExecutor.TrackEnumerable), BindingFlags.Instance | BindingFlags.Public ); - private static readonly MethodInfo NativeEnumeratorTrackQueryExecutorTrackAsync - = typeof(NativeEnumeratorTrackQueryExecutor) + //列表查询追踪方法 + private static readonly MethodInfo TrackAsyncEnumerable + = typeof(NativeTrackQueryExecutor) .GetMethod( - nameof(NativeEnumeratorTrackQueryExecutor.TrackAsync), + nameof(NativeTrackQueryExecutor.TrackAsyncEnumerable), BindingFlags.Instance | BindingFlags.Public ); private readonly IShardingQueryExecutor _shardingQueryExecutor; - private readonly INativeEnumeratorTrackQueryExecutor _nativeEnumeratorTrackQueryExecutor; - private readonly INativeSingleTrackQueryExecutor _nativeSingleTrackQueryExecutor; + private readonly INativeTrackQueryExecutor _nativeTrackQueryExecutor; - public DefaultShardingTrackQueryExecutor(IShardingQueryExecutor shardingQueryExecutor, INativeEnumeratorTrackQueryExecutor nativeEnumeratorTrackQueryExecutor,INativeSingleTrackQueryExecutor nativeSingleTrackQueryExecutor) + public DefaultShardingTrackQueryExecutor(IShardingQueryExecutor shardingQueryExecutor, INativeTrackQueryExecutor nativeTrackQueryExecutor) { _shardingQueryExecutor = shardingQueryExecutor; - _nativeEnumeratorTrackQueryExecutor = nativeEnumeratorTrackQueryExecutor; - _nativeSingleTrackQueryExecutor = nativeSingleTrackQueryExecutor; + _nativeTrackQueryExecutor = nativeTrackQueryExecutor; } public TResult Execute(IQueryCompilerContext queryCompilerContext) { @@ -64,7 +66,16 @@ namespace ShardingCore.Sharding.ShardingExecutors throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint()); } + //native query var result = queryCompilerExecutor.GetQueryCompiler().Execute(queryCompilerExecutor.GetReplaceQueryExpression()); + //native query track + return ResultTrackExecute(result, queryCompilerContext, TrackEnumerable, Track); + + } + + private TResult ResultTrackExecute(TResult result, IQueryCompilerContext queryCompilerContext, + MethodInfo enumerableMethod, MethodInfo entityMethod) + { //native query if (queryCompilerContext.IsParallelQuery() && queryCompilerContext.IsQueryTrack()) { @@ -77,28 +88,27 @@ namespace ShardingCore.Sharding.ShardingExecutors { if (queryCompilerContext.IsEnumerableQuery()) { - return NativeExecute(_nativeEnumeratorTrackQueryExecutor, NativeEnumeratorTrackQueryExecutorTrack, + return DoResultTrackExecute(enumerableMethod, queryCompilerContext, queryEntityType, result); } else if (queryCompilerContext.IsEntityQuery()) { - return NativeExecute(_nativeSingleTrackQueryExecutor, NativeSingleTrackQueryExecutorTrack, + return DoResultTrackExecute(entityMethod, queryCompilerContext, queryEntityType, result); } } return result; } return result; - } - private TResult NativeExecute(object executor, MethodInfo executorMethod, + private TResult DoResultTrackExecute(MethodInfo executorMethod, IQueryCompilerContext queryCompilerContext,Type queryEntityType, TResult result) { return (TResult)executorMethod .MakeGenericMethod(queryEntityType) - .Invoke(executor, new object[] { queryCompilerContext, result }); + .Invoke(_nativeTrackQueryExecutor, new object[] { queryCompilerContext, result }); } #if !EFCORE2 @@ -113,34 +123,14 @@ namespace ShardingCore.Sharding.ShardingExecutors return _shardingQueryExecutor.ExecuteAsync(mergeQueryCompilerContext); } throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint()); - } - var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync(queryCompilerExecutor.GetReplaceQueryExpression(), cancellationToken); //native query - if (queryCompilerContext.IsParallelQuery()&&queryCompilerContext.IsQueryTrack()) - { - var queryEntityType = queryCompilerContext.GetQueryableEntityType(); - var trackerManager = - (ITrackerManager)ShardingContainer.GetService( - typeof(ITrackerManager<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType())); - if (trackerManager.EntityUseTrack(queryEntityType)) - { - if (queryCompilerContext.IsEnumerableQuery()) - { - return NativeExecute(_nativeEnumeratorTrackQueryExecutor, NativeEnumeratorTrackQueryExecutorTrackAsync, - queryCompilerContext,queryEntityType, result); - } - else if (queryCompilerContext.IsEntityQuery()) - { - return NativeExecute(_nativeSingleTrackQueryExecutor, NativeSingleTrackQueryExecutorTrackAsync, - queryCompilerContext, queryEntityType, result); - } - } - return result; - } - return result; + var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync(queryCompilerExecutor.GetReplaceQueryExpression(), cancellationToken); + + //native query track + return ResultTrackExecute(result, queryCompilerContext, TrackAsyncEnumerable, TrackAsync); } #endif #if EFCORE2 @@ -156,31 +146,11 @@ namespace ShardingCore.Sharding.ShardingExecutors } throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint()); } - - var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync(queryCompilerExecutor.GetReplaceQueryExpression()); //native query - if (queryCompilerContext.IsParallelQuery()&&queryCompilerContext.IsQueryTrack()) - { - var queryEntityType = queryCompilerContext.GetQueryableEntityType(); - var trackerManager = - (ITrackerManager)ShardingContainer.GetService( - typeof(ITrackerManager<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType())); - if (trackerManager.EntityUseTrack(queryEntityType)) - { - if (queryCompilerContext.IsEnumerableQuery()) - { - return NativeExecute(_nativeEnumeratorTrackQueryExecutor, NativeEnumeratorTrackQueryExecutorTrack, - queryCompilerContext, queryEntityType, result); - } - else if (queryCompilerContext.IsEntityQuery()) - { - return NativeExecute(_nativeSingleTrackQueryExecutor, NativeSingleTrackQueryExecutorTrack, - queryCompilerContext, queryEntityType, result); - } - } - return result; - } - return result; + var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync(queryCompilerExecutor.GetReplaceQueryExpression()); + + //native query track + return ResultTrackExecute(result, queryCompilerContext, TrackAsyncEnumerable, Track); } public Task ExecuteAsync(IQueryCompilerContext queryCompilerContext, CancellationToken cancellationToken) @@ -194,31 +164,11 @@ namespace ShardingCore.Sharding.ShardingExecutors } throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint()); } - - var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync(queryCompilerExecutor.GetReplaceQueryExpression(), cancellationToken); //native query - if (queryCompilerContext.IsParallelQuery()&&queryCompilerContext.IsQueryTrack()) - { - var queryEntityType = queryCompilerContext.GetQueryableEntityType(); - var trackerManager = - (ITrackerManager)ShardingContainer.GetService( - typeof(ITrackerManager<>).GetGenericType0(queryCompilerContext.GetShardingDbContextType())); - if (trackerManager.EntityUseTrack(queryEntityType)) - { - if (queryCompilerContext.IsEnumerableQuery()) - { - return NativeExecute(_nativeEnumeratorTrackQueryExecutor, NativeEnumeratorTrackQueryExecutorTrack, - queryCompilerContext, queryEntityType, result); - } - else if (queryCompilerContext.IsEntityQuery()) - { - return NativeExecute(_nativeSingleTrackQueryExecutor, NativeSingleTrackQueryExecutorTrack, - queryCompilerContext, queryEntityType, result); - } - } - return result; - } - return result; + var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync(queryCompilerExecutor.GetReplaceQueryExpression(), cancellationToken); + + //native query track + return ResultTrackExecute(result, queryCompilerContext, TrackEnumerable, TrackAsync); } #endif } diff --git a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeEnumeratorTrackQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeEnumeratorTrackQueryExecutor.cs deleted file mode 100644 index a25c11bc..00000000 --- a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeEnumeratorTrackQueryExecutor.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using ShardingCore.Sharding.ShardingExecutors.Abstractions; - -namespace ShardingCore.Sharding.ShardingExecutors.NativeTrackQueries -{ - public interface INativeEnumeratorTrackQueryExecutor - { - IEnumerable Track(IQueryCompilerContext queryCompilerContext, IEnumerable enumerable); - IAsyncEnumerable TrackAsync(IQueryCompilerContext queryCompilerContext, IAsyncEnumerable asyncEnumerable); - } -} diff --git a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeSingleTrackQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeTrackQueryExecutor.cs similarity index 58% rename from src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeSingleTrackQueryExecutor.cs rename to src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeTrackQueryExecutor.cs index 415b502f..3e0dea51 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeSingleTrackQueryExecutor.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/INativeTrackQueryExecutor.cs @@ -7,9 +7,11 @@ using ShardingCore.Sharding.ShardingExecutors.Abstractions; namespace ShardingCore.Sharding.ShardingExecutors.NativeTrackQueries { - public interface INativeSingleTrackQueryExecutor + public interface INativeTrackQueryExecutor { TResult Track(IQueryCompilerContext queryCompilerContext, TResult resultTask); Task TrackAsync(IQueryCompilerContext queryCompilerContext, Task resultTask); + IEnumerable TrackEnumerable(IQueryCompilerContext queryCompilerContext, IEnumerable enumerable); + IAsyncEnumerable TrackAsyncEnumerable(IQueryCompilerContext queryCompilerContext, IAsyncEnumerable asyncEnumerable); } } diff --git a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeEnumeratorTrackQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeEnumeratorTrackQueryExecutor.cs deleted file mode 100644 index 33ce2498..00000000 --- a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeEnumeratorTrackQueryExecutor.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using ShardingCore.Sharding.Enumerators.TrackerEnumerables; -using ShardingCore.Sharding.Enumerators.TrackerEnumerators; -using ShardingCore.Sharding.ShardingExecutors.Abstractions; - -namespace ShardingCore.Sharding.ShardingExecutors.NativeTrackQueries -{ - public class NativeEnumeratorTrackQueryExecutor: INativeEnumeratorTrackQueryExecutor - { - public IEnumerable Track(IQueryCompilerContext queryCompilerContext, IEnumerable enumerable) - { - return new TrackEnumerable(queryCompilerContext.GetShardingDbContext(), enumerable); - } - - public IAsyncEnumerable TrackAsync(IQueryCompilerContext queryCompilerContext,IAsyncEnumerable asyncEnumerable) - { - - return new AsyncTrackerEnumerable(queryCompilerContext.GetShardingDbContext(), asyncEnumerable); - } - } -} diff --git a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeSingleTrackQueryExecutor.cs b/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeTrackQueryExecutor.cs similarity index 67% rename from src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeSingleTrackQueryExecutor.cs rename to src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeTrackQueryExecutor.cs index 32e9d220..30c622fc 100644 --- a/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeSingleTrackQueryExecutor.cs +++ b/src/ShardingCore/Sharding/ShardingExecutors/NativeTrackQueries/NativeTrackQueryExecutor.cs @@ -6,14 +6,15 @@ using System.Threading.Tasks; using ShardingCore.Core.QueryTrackers; using ShardingCore.Core.TrackerManagers; using ShardingCore.Extensions; +using ShardingCore.Sharding.Enumerators.TrackerEnumerables; using ShardingCore.Sharding.ShardingExecutors.Abstractions; namespace ShardingCore.Sharding.ShardingExecutors.NativeTrackQueries { - public class NativeSingleTrackQueryExecutor: INativeSingleTrackQueryExecutor + public class NativeTrackQueryExecutor : INativeTrackQueryExecutor { private readonly IQueryTracker _queryTracker; - public NativeSingleTrackQueryExecutor(IQueryTracker queryTracker) + public NativeTrackQueryExecutor(IQueryTracker queryTracker) { _queryTracker = queryTracker; } @@ -41,6 +42,16 @@ namespace ShardingCore.Sharding.ShardingExecutors.NativeTrackQueries var result = await resultTask; return Track(queryCompilerContext, result); } + public IEnumerable TrackEnumerable(IQueryCompilerContext queryCompilerContext, IEnumerable enumerable) + { + return new TrackEnumerable(queryCompilerContext.GetShardingDbContext(), enumerable); + } + + public IAsyncEnumerable TrackAsyncEnumerable(IQueryCompilerContext queryCompilerContext, IAsyncEnumerable asyncEnumerable) + { + + return new AsyncTrackerEnumerable(queryCompilerContext.GetShardingDbContext(), asyncEnumerable); + } } } diff --git a/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs b/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs index afcfa03e..4bcc7591 100644 --- a/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs +++ b/src/ShardingCore/Sharding/Visitors/QueryableRouteDiscoverVisitor.cs @@ -34,6 +34,7 @@ namespace ShardingCore.Core.Internal.Visitors /// private readonly bool _shardingTableRoute; private Expression> _where = x => true; + private bool useQueryFilterOnFirstWhere = false; private readonly ShardingPredicateResult _noShardingPredicateResult = new ShardingPredicateResult(false, null); @@ -46,6 +47,15 @@ namespace ShardingCore.Core.Internal.Visitors public Expression> GetRouteParseExpression() { + if (!useQueryFilterOnFirstWhere) + { + useQueryFilterOnFirstWhere = true; + if (_entityMetadata.QueryFilterExpression != null) + { + var newWhere= Resolve(_entityMetadata.QueryFilterExpression); + _where = _where.And(newWhere); + } + } return _where; } @@ -59,13 +69,13 @@ namespace ShardingCore.Core.Internal.Visitors var isShardingKey = false; if (_shardingTableRoute) { - isShardingKey = _entityMetadata.ShardingTableProperties.ContainsKey(member.Member.Name); + isShardingKey = _entityMetadata.ShardingTableProperties.ContainsKey(member.Member.Name); } else { isShardingKey = _entityMetadata.ShardingDataSourceProperties.ContainsKey(member.Member.Name); } - return new ShardingPredicateResult(isShardingKey, isShardingKey?member.Member.Name:null); + return new ShardingPredicateResult(isShardingKey, isShardingKey ? member.Member.Name : null); } } @@ -168,7 +178,7 @@ namespace ShardingCore.Core.Internal.Visitors { if (unaryExpression.Operand is LambdaExpression lambdaExpression) { - var newWhere = Resolve(lambdaExpression); + var newWhere = DoResolve(lambdaExpression); _where = _where.And(newWhere); } } @@ -177,6 +187,22 @@ namespace ShardingCore.Core.Internal.Visitors return base.VisitMethodCall(node); } + private Expression> DoResolve(LambdaExpression lambdaExpression) + { + + if (!useQueryFilterOnFirstWhere) + { + useQueryFilterOnFirstWhere = true; + if (_entityMetadata.QueryFilterExpression != null) + { + var body = Expression.AndAlso(lambdaExpression.Body, _entityMetadata.QueryFilterExpression.Body); + var lambda = Expression.Lambda(body, lambdaExpression.Parameters[0]); + return Resolve(lambda); + } + } + return Resolve(lambdaExpression); + } + private Expression> Resolve(Expression expression) { diff --git a/test/ShardingCore.Test/ShardingTest.cs b/test/ShardingCore.Test/ShardingTest.cs index 59a8c423..be9ec562 100644 --- a/test/ShardingCore.Test/ShardingTest.cs +++ b/test/ShardingCore.Test/ShardingTest.cs @@ -428,6 +428,11 @@ namespace ShardingCore.Test var list3 = await queryable1.ToListAsync(); Assert.Equal(1, list3.Count()); Assert.Contains(list3, o => o.Name == "name_300"); + var firstOrDefaultAsync =await queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefaultAsync(); + Assert.NotNull(firstOrDefaultAsync); + var firstOrDefault = queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefault(); + Assert.NotNull(firstOrDefault); + Assert.Equal(firstOrDefaultAsync,firstOrDefault); } [Fact] diff --git a/test/ShardingCore.Test2x/ShardingTest.cs b/test/ShardingCore.Test2x/ShardingTest.cs index dd690f6d..90adb322 100644 --- a/test/ShardingCore.Test2x/ShardingTest.cs +++ b/test/ShardingCore.Test2x/ShardingTest.cs @@ -400,6 +400,11 @@ namespace ShardingCore.Test2x var list3 = await queryable1.ToListAsync(); Assert.Equal(1, list3.Count()); Assert.Contains(list3, o => o.Name == "name_300"); + var firstOrDefaultAsync = await queryable1.OrderBy(o=>o.DateOfMonth).FirstOrDefaultAsync(); + Assert.NotNull(firstOrDefaultAsync); + var firstOrDefault = queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefault(); + Assert.NotNull(firstOrDefault); + Assert.Equal(firstOrDefaultAsync, firstOrDefault); } [Fact] diff --git a/test/ShardingCore.Test3x/ShardingTest.cs b/test/ShardingCore.Test3x/ShardingTest.cs index 82c9fbd8..07474bba 100644 --- a/test/ShardingCore.Test3x/ShardingTest.cs +++ b/test/ShardingCore.Test3x/ShardingTest.cs @@ -399,6 +399,11 @@ namespace ShardingCore.Test3x var list3 = await queryable1.ToListAsync(); Assert.Equal(1, list3.Count()); Assert.Contains(list3, o => o.Name == "name_300"); + var firstOrDefaultAsync = await queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefaultAsync(); + Assert.NotNull(firstOrDefaultAsync); + var firstOrDefault = queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefault(); + Assert.NotNull(firstOrDefault); + Assert.Equal(firstOrDefaultAsync, firstOrDefault); } [Fact] diff --git a/test/ShardingCore.Test5x/ShardingTest.cs b/test/ShardingCore.Test5x/ShardingTest.cs index 5a517f90..87589fb1 100644 --- a/test/ShardingCore.Test5x/ShardingTest.cs +++ b/test/ShardingCore.Test5x/ShardingTest.cs @@ -399,6 +399,11 @@ namespace ShardingCore.Test5x var list3 = await queryable1.ToListAsync(); Assert.Equal(1, list3.Count()); Assert.Contains(list3, o => o.Name == "name_300"); + var firstOrDefaultAsync = await queryable1.OrderBy(o => o.DateOfMonth).FirstOrDefaultAsync(); + Assert.NotNull(firstOrDefaultAsync); + var firstOrDefault = queryable1.OrderBy(o=>o.DateOfMonth).FirstOrDefault(); + Assert.NotNull(firstOrDefault); + Assert.Equal(firstOrDefaultAsync, firstOrDefault); } [Fact]