支持[#88]QueryFilter
This commit is contained in:
parent
04ef52439d
commit
07fd59f288
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -131,8 +131,7 @@ namespace ShardingCore
|
|||
services.TryAddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
|
||||
services.TryAddSingleton<IQueryTracker, QueryTracker>();
|
||||
services.TryAddSingleton<IShardingTrackQueryExecutor, DefaultShardingTrackQueryExecutor>();
|
||||
services.TryAddSingleton<INativeEnumeratorTrackQueryExecutor, NativeEnumeratorTrackQueryExecutor>();
|
||||
services.TryAddSingleton<INativeSingleTrackQueryExecutor, NativeSingleTrackQueryExecutor>();
|
||||
services.TryAddSingleton<INativeTrackQueryExecutor, NativeTrackQueryExecutor>();
|
||||
|
||||
services.TryAddShardingJob();
|
||||
return services;
|
||||
|
|
|
@ -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<TResult>(IQueryCompilerContext queryCompilerContext)
|
||||
{
|
||||
|
@ -64,7 +66,16 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint());
|
||||
}
|
||||
|
||||
//native query
|
||||
var result = queryCompilerExecutor.GetQueryCompiler().Execute<TResult>(queryCompilerExecutor.GetReplaceQueryExpression());
|
||||
//native query track
|
||||
return ResultTrackExecute(result, queryCompilerContext, TrackEnumerable, Track);
|
||||
|
||||
}
|
||||
|
||||
private TResult ResultTrackExecute<TResult>(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<TResult>(object executor, MethodInfo executorMethod,
|
||||
private TResult DoResultTrackExecute<TResult>(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<TResult>(mergeQueryCompilerContext);
|
||||
}
|
||||
throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint());
|
||||
|
||||
}
|
||||
|
||||
|
||||
var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync<TResult>(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<TResult>(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<TResult>(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<TResult>(queryCompilerExecutor.GetReplaceQueryExpression());
|
||||
|
||||
//native query track
|
||||
return ResultTrackExecute(result, queryCompilerContext, TrackAsyncEnumerable, Track);
|
||||
}
|
||||
|
||||
public Task<TResult> ExecuteAsync<TResult>(IQueryCompilerContext queryCompilerContext, CancellationToken cancellationToken)
|
||||
|
@ -194,31 +164,11 @@ namespace ShardingCore.Sharding.ShardingExecutors
|
|||
}
|
||||
throw new ShardingCoreNotFoundException(queryCompilerContext.GetQueryExpression().ShardingPrint());
|
||||
}
|
||||
|
||||
var result = queryCompilerExecutor.GetQueryCompiler().ExecuteAsync<TResult>(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<TResult>(queryCompilerExecutor.GetReplaceQueryExpression(), cancellationToken);
|
||||
|
||||
//native query track
|
||||
return ResultTrackExecute(result, queryCompilerContext, TrackEnumerable, TrackAsync);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -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<TResult> Track<TResult>(IQueryCompilerContext queryCompilerContext, IEnumerable<TResult> enumerable);
|
||||
IAsyncEnumerable<TResult> TrackAsync<TResult>(IQueryCompilerContext queryCompilerContext, IAsyncEnumerable<TResult> asyncEnumerable);
|
||||
}
|
||||
}
|
|
@ -7,9 +7,11 @@ using ShardingCore.Sharding.ShardingExecutors.Abstractions;
|
|||
|
||||
namespace ShardingCore.Sharding.ShardingExecutors.NativeTrackQueries
|
||||
{
|
||||
public interface INativeSingleTrackQueryExecutor
|
||||
public interface INativeTrackQueryExecutor
|
||||
{
|
||||
TResult Track<TResult>(IQueryCompilerContext queryCompilerContext, TResult resultTask);
|
||||
Task<TResult> TrackAsync<TResult>(IQueryCompilerContext queryCompilerContext, Task<TResult> resultTask);
|
||||
IEnumerable<TResult> TrackEnumerable<TResult>(IQueryCompilerContext queryCompilerContext, IEnumerable<TResult> enumerable);
|
||||
IAsyncEnumerable<TResult> TrackAsyncEnumerable<TResult>(IQueryCompilerContext queryCompilerContext, IAsyncEnumerable<TResult> asyncEnumerable);
|
||||
}
|
||||
}
|
|
@ -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<TResult> Track<TResult>(IQueryCompilerContext queryCompilerContext, IEnumerable<TResult> enumerable)
|
||||
{
|
||||
return new TrackEnumerable<TResult>(queryCompilerContext.GetShardingDbContext(), enumerable);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<TResult> TrackAsync<TResult>(IQueryCompilerContext queryCompilerContext,IAsyncEnumerable<TResult> asyncEnumerable)
|
||||
{
|
||||
|
||||
return new AsyncTrackerEnumerable<TResult>(queryCompilerContext.GetShardingDbContext(), asyncEnumerable);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<TResult> TrackEnumerable<TResult>(IQueryCompilerContext queryCompilerContext, IEnumerable<TResult> enumerable)
|
||||
{
|
||||
return new TrackEnumerable<TResult>(queryCompilerContext.GetShardingDbContext(), enumerable);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<TResult> TrackAsyncEnumerable<TResult>(IQueryCompilerContext queryCompilerContext, IAsyncEnumerable<TResult> asyncEnumerable)
|
||||
{
|
||||
|
||||
return new AsyncTrackerEnumerable<TResult>(queryCompilerContext.GetShardingDbContext(), asyncEnumerable);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
/// </summary>
|
||||
private readonly bool _shardingTableRoute;
|
||||
private Expression<Func<string, bool>> _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<Func<string, bool>> GetRouteParseExpression()
|
||||
{
|
||||
if (!useQueryFilterOnFirstWhere)
|
||||
{
|
||||
useQueryFilterOnFirstWhere = true;
|
||||
if (_entityMetadata.QueryFilterExpression != null)
|
||||
{
|
||||
var newWhere= Resolve(_entityMetadata.QueryFilterExpression);
|
||||
_where = _where.And(newWhere);
|
||||
}
|
||||
}
|
||||
return _where;
|
||||
}
|
||||
|
||||
|
@ -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<Func<string, bool>> 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<Func<string, bool>> Resolve(Expression expression)
|
||||
{
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
Loading…
Reference in New Issue