添加表达式缓存,获取默认字符串优化,发布x.3.1.62

This commit is contained in:
xuejiaming 2021-12-02 18:44:52 +08:00
parent c23d72bca3
commit 0d59baa5cb
17 changed files with 239 additions and 135 deletions

View File

@ -11,13 +11,16 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore;
using ShardingCore.Bootstrapers;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ShardingDbContextExecutors;
using ShardingCore6x.NoShardingDbContexts;
using ShardingCore6x.ShardingDbContexts;
@ -32,20 +35,24 @@ namespace ShardingCore6x
private readonly IVirtualTable<Order> _virtualTable;
private readonly IRouteTailFactory _routeTailFactory;
private readonly IStreamMergeContextFactory<DefaultShardingDbContext> _streamMergeContextFactory;
private readonly ActualConnectionStringManager<DefaultShardingDbContext> _actualConnectionStringManager;
private readonly IVirtualDataSource<DefaultShardingDbContext> _virtualDataSource;
public EFCoreCrud()
{
var services = new ServiceCollection();
services.AddDbContext<DefaultDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=db1;Integrated Security=True;"), ServiceLifetime.Transient, ServiceLifetime.Transient);
services.AddDbContext<DefaultDbContext>(o => o.UseMySql("server=127.0.0.1;port=3306;database=db1;userid=root;password=;", new MySqlServerVersion(new Version()))
//UseSqlServer("Data Source=localhost;Initial Catalog=db1;Integrated Security=True;")
, ServiceLifetime.Transient, ServiceLifetime.Transient);
services.AddLogging();
services.AddShardingDbContext<DefaultShardingDbContext>((conStr, builder) => builder.UseSqlServer(conStr), ServiceLifetime.Transient, ServiceLifetime.Transient)
services.AddShardingDbContext<DefaultShardingDbContext>((conStr, builder) => builder.UseMySql(conStr, new MySqlServerVersion(new Version())), ServiceLifetime.Transient, ServiceLifetime.Transient)
.Begin(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AutoTrackEntity = false;
}).AddShardingTransaction((connection, builder) => builder.UseSqlServer(connection))
.AddDefaultDataSource("ds0", "Data Source=localhost;Initial Catalog=db2;Integrated Security=True;")
}).AddShardingTransaction((connection, builder) => builder.UseMySql(connection, new MySqlServerVersion(new Version())))
.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=db2;userid=root;password=;")//"Data Source=localhost;Initial Catalog=db2;Integrated Security=True;")
.AddShardingTableRoute(op =>
{
op.AddShardingTableRoute<OrderVirtualTableRoute>();
@ -107,9 +114,11 @@ namespace ShardingCore6x
_defaultShardingDbContext = ShardingContainer.GetService<DefaultShardingDbContext>();
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<DefaultShardingDbContext>>();
_virtualTable = _virtualTableManager.GetVirtualTable<Order>();
_routeTailFactory= ShardingContainer.GetService<IRouteTailFactory>();
_routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
_streamMergeContextFactory =
ShardingContainer.GetService<IStreamMergeContextFactory<DefaultShardingDbContext>>();
_actualConnectionStringManager = new ActualConnectionStringManager<DefaultShardingDbContext>();
_virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<DefaultShardingDbContext>>();
}
@ -118,16 +127,45 @@ namespace ShardingCore6x
public int N;
[Benchmark]
public async Task NoRouteParseCache()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 3000000).ToString();
var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
_virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
}
}
//private static readonly string[] aa = new string[] { "a", "b", "c", "d" };
//[Benchmark]
//public void ShardingCreateDbContextFirstOrDefault()
//{
// for (int i = 0; i < N; i++)
// {
// var routeTail = _routeTailFactory.Create(aa[i % 4]);
// var dbContext = _defaultShardingDbContext.GetDbContext("ds0", true, routeTail);
// }
//}
//[Benchmark]
//public void ActualConnectionStringManager()
//{
// for (int i = 0; i < N; i++)
// {
// var connectionString = _actualConnectionStringManager.GetConnectionString("ds0", false);
// }
//}
//[Benchmark]
//public async Task ShardingCreateStreamMergeContext()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1000000, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// var firstOrDefaultAsync = _streamMergeContextFactory.Create(queryable, _defaultShardingDbContext);
// }
//}
//[Benchmark]
//public async Task NoRouteParseCache()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 3000000).ToString();
// var queryable = _defaultShardingDbContext.Set<Order>().Where(o => o.Id == next);
// _virtualTable.RouteTo(new ShardingTableRouteConfig(queryable: queryable));
// }
//}
//[Benchmark]
//public async Task ShardingFirstOrDefaultAsync()
@ -145,7 +183,7 @@ namespace ShardingCore6x
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 3000000).ToString();
var next = new Random().Next(1, 7000000).ToString();
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
}
}
@ -154,7 +192,7 @@ namespace ShardingCore6x
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 3000000).ToString();
var next = new Random().Next(1, 7000000).ToString();
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
}
}
@ -178,100 +216,120 @@ namespace ShardingCore6x
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == next);
// }
//}
//[Benchmark]
//public async Task NoShardingNoIndexFirstOrDefaultAsync100w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 1000000);
// }
//}
[Benchmark]
public async Task NoShardingNoIndexFirstOrDefaultAsync()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync1 = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 0);
var firstOrDefaultAsync2 = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 999999);
}
}
//[Benchmark]
//public async Task ShardingNoIndexFirstOrDefaultAsync100w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 1000000);
// }
//}
//[Benchmark]
//public async Task NoShardingNoIndexCountAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().CountAsync(o => o.Amount == 3000000);
// }
//}
[Benchmark]
public async Task ShardingNoIndexFirstOrDefaultAsync()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync1 = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 0);
var firstOrDefaultAsync2 = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 999999);
}
}
[Benchmark]
public async Task NoShardingNoIndexCountAsync()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync1 = await _defaultDbContext.Set<Order>().CountAsync(o => o.Amount == 0);
var firstOrDefaultAsync2 = await _defaultDbContext.Set<Order>().CountAsync(o => o.Amount == 999999);
}
}
//[Benchmark]
//public async Task ShardingNoIndexCountASYNC()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().CountAsync(o => o.Amount == 3000000);
// }
//}
//[Benchmark]
//public async Task NoShardingNoIndexFirstOrDefaultAsync600w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 6000000);
// }
//}
//[Benchmark]
//public async Task ShardingNoIndexFirstOrDefaultAsync600w()
//{
// for (int i = 0; i < N; i++)
// {
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 6000000);
// }
//}
[Benchmark]
public async Task ShardingNoIndexCountAsync()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync1 = await _defaultShardingDbContext.Set<Order>().CountAsync(o => o.Amount == 0);
var firstOrDefaultAsync2 = await _defaultShardingDbContext.Set<Order>().CountAsync(o => o.Amount == 999999);
}
}
[Benchmark]
public async Task NoShardingNoIndexFirstOrDefaultAsync0w()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 0);
}
}
[Benchmark]
public async Task ShardingNoIndexFirstOrDefaultAsync0w()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 0);
}
}
[Benchmark]
public async Task NoShardingNoIndexFirstOrDefaultAsync99w()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 999999);
}
}
[Benchmark]
public async Task ShardingNoIndexFirstOrDefaultAsync99w()
{
for (int i = 0; i < N; i++)
{
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Amount == 999999);
}
}
//[Benchmark]
//public async Task NoShardingNoIndexLikeToListAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 8000000).ToString();
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().Where(o => o.Body.Contains(next)).FirstOrDefaultAsync();
// }
//}
[Benchmark]
public async Task NoShardingNoIndexLikeToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000).ToString();
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().Where(o => o.Body.Contains(next)).ToListAsync();
}
}
//[Benchmark]
//public async Task ShardingNoIndexLikeToListAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(1, 8000000).ToString();
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Body.Contains(next)).FirstOrDefaultAsync();
// }
//}
//[Benchmark]
//public async Task NoShardingNoIndexToListAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(5000000, 7000000);
// var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().Where(o => o.Amount == next).ToListAsync();
// }
//}
[Benchmark]
public async Task ShardingNoIndexLikeToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000).ToString();
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Body.Contains(next)).ToListAsync();
}
}
[Benchmark]
public async Task NoShardingNoIndexToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000);
var firstOrDefaultAsync = await _defaultDbContext.Set<Order>().Where(o => o.Amount == next).ToListAsync();
}
}
//[Benchmark]
//public async Task ShardingNoIndexToListAsync()
//{
// for (int i = 0; i < N; i++)
// {
// var next = new Random().Next(5000000, 7000000);
// var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Amount == next).ToListAsync();
// }
//}
[Benchmark]
public async Task ShardingNoIndexToListAsync()
{
for (int i = 0; i < N; i++)
{
var next = new Random().Next(1, 7000000);
var firstOrDefaultAsync = await _defaultShardingDbContext.Set<Order>().Where(o => o.Amount == next).ToListAsync();
}
}
//[Benchmark]
//public void ShardingRouteFirstOrDefault()
//{

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -12,6 +12,8 @@
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="EFCore.BulkExtensions" Version="6.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.0" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="6.13.2" />
</ItemGroup>
<ItemGroup>

View File

@ -11,6 +11,8 @@ namespace ShardingCore6x.ShardingDbContexts
{
internal class OrderVirtualTableRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute<Order>
{
public override bool EnableRouteParseCompileCache => true;
public OrderVirtualTableRoute() : base(2, 5)
{
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@ -1,9 +1,9 @@
:start
::定义版本
set EFCORE2=2.3.1.61
set EFCORE3=3.3.1.61
set EFCORE5=5.3.1.61
set EFCORE6=6.3.1.61
set EFCORE2=2.3.1.62
set EFCORE3=3.3.1.62
set EFCORE5=5.3.1.62
set EFCORE6=6.3.1.62
::删除所有bin与obj下的文件
@echo off

View File

@ -78,6 +78,7 @@ namespace ShardingCore.Bootstrapers
_virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(_shardingConfigOption.DefaultDataSourceName, _shardingConfigOption.DefaultConnectionString, true));
InitializeEntityMetadata();
InitializeConfigure();
_virtualDataSource.CheckVirtualDataSource();
}
private void InitializeEntityMetadata()

View File

@ -46,6 +46,12 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
/// </exception>
/// <returns></returns>
IPhysicDataSource GetPhysicDataSource(string dataSourceName);
/// <summary>
/// 获取数据库链接字符串
/// </summary>
/// <param name="dataSourceName"></param>
/// <returns></returns>
string GetConnectionString(string dataSourceName);
/// <summary>
/// 添加物理表 add physic data source
@ -56,6 +62,10 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
bool IsDefault(string dataSourceName);
/// <summary>
/// 初始化检查数据源
/// </summary>
void CheckVirtualDataSource();
}
/// <summary>
/// 虚拟数据源 连接所有的实际数据源

View File

@ -32,6 +32,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
new ConcurrentDictionary<string, IPhysicDataSource>();
public string DefaultDataSourceName { get; private set; }
public string DefaultConnectionString { get; private set; }
public VirtualDataSource(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
{
@ -101,6 +102,13 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
return physicDataSource;
}
public string GetConnectionString(string dataSourceName)
{
if (IsDefault(dataSourceName))
return DefaultConnectionString;
return GetPhysicDataSource(DefaultDataSourceName).ConnectionString;
}
public bool AddPhysicDataSource(IPhysicDataSource physicDataSource)
{
if (physicDataSource.IsDefault)
@ -109,8 +117,8 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
{
throw new ShardingCoreInvalidOperationException($"default data source name:[{DefaultDataSourceName}],add physic default data source name:[{physicDataSource.DataSourceName}]");
}
DefaultDataSourceName = physicDataSource.DataSourceName;
DefaultConnectionString = physicDataSource.ConnectionString;
}
return _physicDataSources.TryAdd(physicDataSource.DataSourceName, physicDataSource);
}
@ -125,12 +133,19 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
public bool IsDefault(string dataSourceName)
{
if (string.IsNullOrWhiteSpace(DefaultDataSourceName))
{
throw new ShardingCoreInvalidOperationException("virtual data source not inited");
}
return DefaultDataSourceName== dataSourceName;
return DefaultDataSourceName == dataSourceName;
}
public void CheckVirtualDataSource()
{
if (string.IsNullOrWhiteSpace(DefaultDataSourceName))
throw new ShardingCoreInvalidOperationException(
$"virtual data source not inited {nameof(DefaultDataSourceName)} in IShardingDbContext null");
if (string.IsNullOrWhiteSpace(DefaultConnectionString))
throw new ShardingCoreInvalidOperationException(
$"virtual data source not inited {nameof(DefaultConnectionString)} in IShardingDbContext null");
}
}
}

View File

@ -23,7 +23,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
//获取路由后缀表达式
var routeParseExpression = ShardingUtil.GetRouteParseExpression<TKey>(queryable, EntityMetadata, GetRouteToFilter,true);
//表达式缓存编译
var filter=CachingCompile(routeParseExpression);
var filter =CachingCompile(routeParseExpression);
//通过编译结果进行过滤
var physicTables = allPhysicTables.Where(o => filter(o.Tail)).ToList();
return physicTables;

View File

@ -21,13 +21,6 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
/// </summary>
public static Func<string, bool> FromCache(this Expression<Func<string,bool>> query)
{
var startNew = Stopwatch.StartNew();
for (int i = 0; i < 300; i++)
{
string key1 = query.GetCacheKey();
}
startNew.Stop();
var x = startNew.ElapsedMilliseconds;
string key = query.GetCacheKey();
return _routeFilter.GetOrAdd(key, k => query.Compile());

View File

@ -60,7 +60,7 @@ namespace ShardingCore.Sharding
}
private string GetWriteConnectionString(string dataSourceName)
{
return _virtualDataSource.GetPhysicDataSource(dataSourceName).ConnectionString;
return _virtualDataSource.GetConnectionString(dataSourceName);
}
private string GetReadWriteSeparationConnectString(string dataSourceName)

View File

@ -21,7 +21,7 @@ namespace ShardingCore.Sharding
}
public string GetConnectionString(string dataSourceName)
{
return _virtualDataSource.GetPhysicDataSource(dataSourceName).ConnectionString;
return _virtualDataSource.GetConnectionString(dataSourceName);
}
}
}

View File

@ -25,7 +25,7 @@ namespace ShardingCore.Sharding.MergeEngines.Abstractions.InMemoryMerge.Abstract
{
if (secondExpression is UnaryExpression where)
{
if (where.Operand is LambdaExpression lambdaExpression && lambdaExpression is Expression<Func<TEntity, bool>> predicate)
if (@where.Operand is LambdaExpression lambdaExpression and Expression<Func<TEntity, bool>> predicate)
{
return queryable.Where(predicate);
}

View File

@ -166,6 +166,8 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
private TResult GenericShardingDbContextMergeExecute<TResult>(Type streamMergeEngineType, IShardingDbContext shardingDbContext, MethodCallExpression query, bool async, CancellationToken cancellationToken)
{
//{
// var startNew1 = Stopwatch.StartNew();
// var queryEntityType = query.GetQueryEntityType();
// var newStreamMergeEngineType = streamMergeEngineType.MakeGenericType(shardingDbContext.GetType(), queryEntityType);
@ -181,21 +183,19 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
// // var x = startNew.ElapsedMilliseconds;
// //}
// {
// //获取所有需要路由的表后缀
// var startNew1 = Stopwatch.StartNew();
// for (int i = 0; i < 1; i++)
// for (int i = 0; i < 10; i++)
// {
// var streamEngine = Activator.CreateInstance(typeof(AAA), shardingDbContext, query);
// }
// startNew1.Stop();
// var x = startNew1.ElapsedMilliseconds;
// }
// var methodName = async ? nameof(IGenericMergeResult.MergeResultAsync) : nameof(IGenericMergeResult.MergeResult);
// var streamEngineMethod = newStreamMergeEngineType.GetMethod(methodName);
// if (streamEngineMethod == null)
// throw new ShardingCoreException($"cant found InMemoryAsyncStreamMergeEngine method [{methodName}]");
// var @params = async ? new object[] { cancellationToken } : new object[0];
// startNew1.Stop();
// var x = startNew1.ElapsedMilliseconds;
// Console.WriteLine("----------------------"+x);
//}
{

View File

@ -94,7 +94,9 @@ namespace ShardingCore.Core.Internal.Visitors
private TKey GetShardingKeyValue(Expression expression)
{
if (expression is ConstantExpression constantExpression)
{
return (TKey)constantExpression.Value;
}
if (expression is UnaryExpression unaryExpression)
{
return Expression.Lambda<Func<TKey>>(unaryExpression.Operand).Compile()();
@ -102,11 +104,24 @@ namespace ShardingCore.Core.Internal.Visitors
if (expression is MemberExpression member1Expression)
{
//var target = GetShardingKeyValue(member1Expression.Expression);
//if (member1Expression.Member is FieldInfo field)
// return field.GetValue(target);
//if (member1Expression.Member is PropertyInfo property)
// return property.GetValue(target);
if (member1Expression.Expression is ConstantExpression memberConstantExpression)
{
if (member1Expression.Member is FieldInfo memberFieldInfo)
{
object container = memberConstantExpression.Value;
return (TKey)memberFieldInfo.GetValue(container);
}
if (member1Expression.Member is PropertyInfo memberPropertyInfo)
{
object container = memberConstantExpression.Value;
return (TKey)memberPropertyInfo.GetValue(container);
}
else if (memberConstantExpression.Value is TKey shardingKeyValue)
{
return shardingKeyValue;
}
}
return Expression.Lambda<Func<TKey>>(member1Expression).Compile()();
}

View File

@ -445,7 +445,15 @@ namespace ShardingCore.Test
[Fact]
public async Task FirstOrDefault2()
{
var sysUserModabxxxxx = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth>=202102).FirstOrDefaultAsync();
var sysUserModabxxxxx1 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth >= 202102).FirstOrDefaultAsync();
var sysUserModabxxxxx2 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth >= 202101).FirstOrDefaultAsync();
var sysUserModabxxxxx3 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth > 202102).FirstOrDefaultAsync();
var sysUserModabxxxxx4 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth == 202102).FirstOrDefaultAsync();
var sysUserModabxxxxx5 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth < 202102).FirstOrDefaultAsync();
var sysUserModabxxxxx6 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth <= 202102).FirstOrDefaultAsync();
var sysUserModabxxxxx7 = await _virtualDbContext.Set<SysUserSalary>().Where(o => o.DateOfMonth >= 202102).FirstOrDefaultAsync();
var next = "1";
var sysUserMod1 = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == next).FirstOrDefaultAsync();
var sysUserModabxxx = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_2").FirstOrDefaultAsync();
var sysUserModabxxx11 = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_2"|| o.Name == "name_3").FirstOrDefaultAsync();
var x=new Object [] { "1", "2" };