support route must

This commit is contained in:
xuejiaming 2021-08-24 10:05:47 +08:00
parent 635b509811
commit fdbeef0343
18 changed files with 378 additions and 21 deletions

View File

@ -1,8 +1,8 @@
:start :start
::定义版本 ::定义版本
set EFCORE2=2.2.0.09 set EFCORE2=2.2.0.10-pre
set EFCORE3=3.2.0.09 set EFCORE3=3.2.0.10-pre
set EFCORE5=5.2.0.09 set EFCORE5=5.2.0.10-pre
::删除所有bin与obj下的文件 ::删除所有bin与obj下的文件
@echo off @echo off

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ShardingCore.Core.QueryRouteManagers.Abstractions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 16:54:19
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public interface IShardingRouteAccessor
{
ShardingRouteContext ShardingRouteContext { get; set; }
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ShardingCore.Core.QueryRouteManagers.Abstractions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 16:53:05
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public interface IShardingRouteManager
{
ShardingRouteContext Current { get; }
/// <summary>
/// 创建路由scope
/// </summary>
/// <returns></returns>
ShardingRouteScope CreateScope();
}
}

View File

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
namespace ShardingCore.Core.QueryRouteManagers
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 17:10:00
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRouteAccessor: IShardingRouteAccessor
{
private static AsyncLocal<ShardingRouteContext> _shardingRouteContext = new AsyncLocal<ShardingRouteContext>();
/// <inheritdoc />
public ShardingRouteContext ShardingRouteContext
{
get => _shardingRouteContext.Value;
set => _shardingRouteContext.Value = value;
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Text;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
namespace ShardingCore.Core.QueryRouteManagers
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 16:55:33
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRouteContext
{
public Dictionary<Type, HashSet<string>> Must { get; }
public Dictionary<Type, HashSet<string>> Should { get; }
public Dictionary<Type, HashSet<string>> ShouldNot { get; }
private ShardingRouteContext()
{
Must = new Dictionary<Type, HashSet<string>>();
Should = new Dictionary<Type, HashSet<string>>();
ShouldNot = new Dictionary<Type, HashSet<string>>();
}
public static ShardingRouteContext Create()
{
return new ShardingRouteContext();
}
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Text;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
namespace ShardingCore.Core.QueryRouteManagers
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 21:55:57
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRouteManager: IShardingRouteManager
{
private readonly IShardingRouteAccessor _shardingRouteAccessor;
public ShardingRouteManager(IShardingRouteAccessor shardingRouteAccessor)
{
_shardingRouteAccessor = shardingRouteAccessor;
}
public ShardingRouteContext Current => _shardingRouteAccessor.ShardingRouteContext;
public ShardingRouteScope CreateScope()
{
var shardingRouteScope = new ShardingRouteScope(_shardingRouteAccessor);
_shardingRouteAccessor.ShardingRouteContext = ShardingRouteContext.Create();
return shardingRouteScope;
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
namespace ShardingCore.Core.QueryRouteManagers
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 16:53:43
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRouteScope : IDisposable
{
/// <summary>
/// 分表配置访问器
/// </summary>
public IShardingRouteAccessor ShardingRouteAccessor { get; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="shardingRouteAccessor"></param>
public ShardingRouteScope(IShardingRouteAccessor shardingRouteAccessor)
{
ShardingRouteAccessor = shardingRouteAccessor;
}
/// <summary>
/// 回收
/// </summary>
public void Dispose()
{
ShardingRouteAccessor.ShardingRouteContext = null;
}
}
}

View File

@ -23,6 +23,7 @@ namespace ShardingCore.Core.ShardingAccessors
/// <param name="shardingAccessor"></param> /// <param name="shardingAccessor"></param>
public ShardingScope(IShardingAccessor shardingAccessor) public ShardingScope(IShardingAccessor shardingAccessor)
{ {
shardingAccessor.ShardingContext = null;
ShardingAccessor = shardingAccessor; ShardingAccessor = shardingAccessor;
} }

View File

@ -17,7 +17,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
*/ */
public abstract class AbstractShardingOperatorVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class, IShardingTable public abstract class AbstractShardingOperatorVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class, IShardingTable
{ {
protected override List<IPhysicTable> DoRouteWithWhere(List<IPhysicTable> allPhysicTables, IQueryable queryable) protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
{ {
//获取所有需要路由的表后缀 //获取所有需要路由的表后缀
var filter = ShardingKeyUtil.GetRouteShardingTableFilter(queryable, ShardingKeyUtil.Parse(typeof(T)), ConvertToShardingKey, GetRouteToFilter); var filter = ShardingKeyUtil.GetRouteShardingTableFilter(queryable, ShardingKeyUtil.Parse(typeof(T)), ConvertToShardingKey, GetRouteToFilter);

View File

@ -2,19 +2,31 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ShardingCore.Core.PhysicTables; using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.QueryRouteManagers;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
namespace ShardingCore.Core.VirtualRoutes.TableRoutes namespace ShardingCore.Core.VirtualRoutes.TableRoutes
{ {
/* /*
* @Author: xjm * @Author: xjm
* @Description: * @Description:
* @Date: Friday, 18 December 2020 14:33:01 * @Date: Friday, 18 December 2020 14:33:01
* @Email: 326308290@qq.com * @Email: 326308290@qq.com
*/ */
public abstract class AbstractVirtualTableRoute<T, TKey> : IVirtualTableRoute<T> where T : class, IShardingTable public abstract class AbstractVirtualTableRoute<T, TKey> : IVirtualTableRoute<T> where T : class, IShardingTable
{ {
public Type ShardingEntityType => typeof(T); public Type ShardingEntityType => typeof(T);
public virtual ShardingRouteContext CurrentShardingRouteContext =>
ShardingContainer.GetService<IShardingRouteManager>().Current;
/// <summary>
/// 跳过表达式路由
/// </summary>
protected virtual bool SkipRouteWithPredicate =>
CurrentShardingRouteContext != null && CurrentShardingRouteContext.TryGetMustTail<T>(out HashSet<string> mustTails) && mustTails.IsNotEmpty();
protected abstract TKey ConvertToShardingKey(object shardingKey); protected abstract TKey ConvertToShardingKey(object shardingKey);
public abstract string ShardingKeyToTail(object shardingKey); public abstract string ShardingKeyToTail(object shardingKey);
/// <summary> /// <summary>
@ -23,9 +35,24 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
/// <param name="allPhysicTables"></param> /// <param name="allPhysicTables"></param>
/// <param name="queryable"></param> /// <param name="queryable"></param>
/// <returns></returns> /// <returns></returns>
public List<IPhysicTable> RouteWithWhere(List<IPhysicTable> allPhysicTables, IQueryable queryable) public virtual List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
{ {
return AfterPhysicTableFilter(allPhysicTables,DoRouteWithWhere(allPhysicTables,queryable)); if (SkipRouteWithPredicate)
{
var tails = CurrentShardingRouteContext.Must[ShardingEntityType];
var physicTables = allPhysicTables.Where(o => tails.Contains(o.Tail)).ToList();
if (physicTables.IsEmpty())
throw new ShardingCoreException(
$" sharding route must error:[{ShardingEntityType.FullName}]-->[{string.Join(",",tails)}]");
return physicTables;
}
var filterPhysicTables = BeforePhysicTableFilter(allPhysicTables);
filterPhysicTables = DoRouteWithPredicate(filterPhysicTables, queryable);
return AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
}
protected virtual List<IPhysicTable> BeforePhysicTableFilter(List<IPhysicTable> allPhysicTables)
{
return allPhysicTables;
} }
/// <summary> /// <summary>
/// 实际路由 /// 实际路由
@ -33,14 +60,14 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
/// <param name="allPhysicTables"></param> /// <param name="allPhysicTables"></param>
/// <param name="queryable"></param> /// <param name="queryable"></param>
/// <returns></returns> /// <returns></returns>
protected abstract List<IPhysicTable> DoRouteWithWhere(List<IPhysicTable> allPhysicTables, IQueryable queryable); protected abstract List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
/// <summary> /// <summary>
/// 物理表过滤后 /// 物理表过滤后
/// </summary> /// </summary>
/// <param name="allPhysicTables">所有的物理表</param> /// <param name="allPhysicTables">所有的物理表</param>
/// <param name="filterPhysicTables">过滤后的物理表</param> /// <param name="filterPhysicTables">过滤后的物理表</param>
/// <returns></returns> /// <returns></returns>
public virtual List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables,List<IPhysicTable> filterPhysicTables) protected virtual List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
{ {
return filterPhysicTables; return filterPhysicTables;
} }

View File

@ -25,7 +25,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
/// <param name="allPhysicTables"></param> /// <param name="allPhysicTables"></param>
/// <param name="queryable"></param> /// <param name="queryable"></param>
/// <returns></returns> /// <returns></returns>
List<IPhysicTable> RouteWithWhere(List<IPhysicTable> allPhysicTables,IQueryable queryable); List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables,IQueryable queryable);
/// <summary> /// <summary>
/// 根据值进行路由 /// 根据值进行路由

View File

@ -45,9 +45,9 @@ namespace ShardingCore.Core.VirtualTables
{ {
var route = _virtualTableRoute; var route = _virtualTableRoute;
if (tableRouteConfig.UseQueryable()) if (tableRouteConfig.UseQueryable())
return route.RouteWithWhere(_physicTables, tableRouteConfig.GetQueryable()); return route.RouteWithPredicate(_physicTables, tableRouteConfig.GetQueryable());
if (tableRouteConfig.UsePredicate()) if (tableRouteConfig.UsePredicate())
return route.RouteWithWhere(_physicTables, new EnumerableQuery<T>((Expression<Func<T, bool>>) tableRouteConfig.GetPredicate())); return route.RouteWithPredicate(_physicTables, new EnumerableQuery<T>((Expression<Func<T, bool>>) tableRouteConfig.GetPredicate()));
object shardingKeyValue = null; object shardingKeyValue = null;
if (tableRouteConfig.UseValue()) if (tableRouteConfig.UseValue())
shardingKeyValue = tableRouteConfig.GetShardingKeyValue(); shardingKeyValue = tableRouteConfig.GetShardingKeyValue();

View File

@ -12,6 +12,8 @@ using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions; using ShardingCore.Sharding.Abstractions;
using ShardingCore.TableCreator; using ShardingCore.TableCreator;
using System; using System;
using ShardingCore.Core.QueryRouteManagers;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Core.ShardingAccessors; using ShardingCore.Core.ShardingAccessors;
using ShardingCore.Core.ShardingAccessors.Abstractions; using ShardingCore.Core.ShardingAccessors.Abstractions;
using ShardingCore.Core.VirtualRoutes; using ShardingCore.Core.VirtualRoutes;
@ -84,6 +86,8 @@ namespace ShardingCore
services.AddSingleton<IShardingAccessor, ShardingAccessor>(); services.AddSingleton<IShardingAccessor, ShardingAccessor>();
services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>(); services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
services.AddSingleton<IRouteTailFactory, RouteTailFactory>(); services.AddSingleton<IRouteTailFactory, RouteTailFactory>();
services.AddSingleton<IShardingRouteManager, ShardingRouteManager>();
services.AddSingleton<IShardingRouteAccessor, ShardingRouteAccessor>();
return services; return services;
} }

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
using ShardingCore.Core;
using ShardingCore.Core.QueryRouteManagers;
using ShardingCore.Exceptions;
namespace ShardingCore.Extensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/8/23 22:19:24
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public static class ShardingRouteExtension
{
public static bool TryGetMustTail<TEntity>(this ShardingRouteContext shardingRouteContext, out HashSet<string> tail) where TEntity : class,IShardingTable
{
return TryGetMustTail(shardingRouteContext,typeof(TEntity),out tail);
}
public static bool TryGetMustTail(this ShardingRouteContext shardingRouteContext,Type entityType, out HashSet<string> tail)
{
if (shardingRouteContext == null)
{
tail = null;
return false;
}
if (!entityType.IsShardingTable())
throw new ShardingCoreException($"sharding route entity type :{entityType.FullName} must impl {nameof(IShardingTable)}");
if (!shardingRouteContext.Must.ContainsKey(entityType))
{
tail = null;
return false;
}
tail = shardingRouteContext.Must[entityType];
return true;
}
}
}

View File

@ -66,7 +66,7 @@ namespace ShardingCore.TableCreator
var shardingConfigOptions = _shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == shardingDbContextType); var shardingConfigOptions = _shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == shardingDbContextType);
if (shardingConfigOptions == null) if (shardingConfigOptions == null)
throw new ShardingCoreException( throw new ShardingCoreException(
"not found sharding config options db context is {shardingDbContextType.FullName}"); $"not found sharding config options db context is {shardingDbContextType.FullName}");
using (var serviceScope = _serviceProvider.CreateScope()) using (var serviceScope = _serviceProvider.CreateScope())
{ {
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntityType); var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntityType);

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine; using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.DbContexts.VirtualDbContexts; using ShardingCore.DbContexts.VirtualDbContexts;
using ShardingCore.Extensions; using ShardingCore.Extensions;
@ -20,10 +22,12 @@ namespace ShardingCore.Test50
public class ShardingTest public class ShardingTest
{ {
private readonly ShardingDefaultDbContext _virtualDbContext; private readonly ShardingDefaultDbContext _virtualDbContext;
private readonly IShardingRouteManager _shardingRouteManager;
public ShardingTest(ShardingDefaultDbContext virtualDbContext) public ShardingTest(ShardingDefaultDbContext virtualDbContext,IShardingRouteManager shardingRouteManager)
{ {
_virtualDbContext = virtualDbContext; _virtualDbContext = virtualDbContext;
_shardingRouteManager = shardingRouteManager;
} }
//[Fact] //[Fact]
@ -44,6 +48,36 @@ namespace ShardingCore.Test50
// Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail))); // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail)));
//} //}
[Fact] [Fact]
public async Task ToList_All_Route_Test()
{
using (_shardingRouteManager.CreateScope())
{
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(333, mod00s.Count);
}
var mods = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(1000, mods.Count);
var modOrders1 = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
int ascAge = 1;
foreach (var sysUserMod in modOrders1)
{
Assert.Equal(ascAge, sysUserMod.Age);
ascAge++;
}
var modOrders2 = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToListAsync();
int descAge = 1000;
foreach (var sysUserMod in modOrders2)
{
Assert.Equal(descAge, sysUserMod.Age);
descAge--;
}
}
[Fact]
public async Task ToList_All_Test() public async Task ToList_All_Test()
{ {
@ -81,6 +115,7 @@ namespace ShardingCore.Test50
DateOfMonth = salary.DateOfMonth, DateOfMonth = salary.DateOfMonth,
Name = u.Name Name = u.Name
}).ToListAsync(); }).ToListAsync();
var list2 = list.OrderBy(o=>o.Age).Select(o=>o.Age).Distinct().ToList(); var list2 = list.OrderBy(o=>o.Age).Select(o=>o.Age).Distinct().ToList();
Assert.Equal(24000, list.Count()); Assert.Equal(24000, list.Count());
Assert.Equal(24, list.Count(o => o.Name == "name_200")); Assert.Equal(24, list.Count(o => o.Name == "name_200"));

View File

@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Test50_2x.Domain.Entities; using ShardingCore.Test50_2x.Domain.Entities;
using Xunit; using Xunit;
@ -15,10 +17,12 @@ namespace ShardingCore.Test50_2x
public class ShardingTest public class ShardingTest
{ {
private readonly ShardingDefaultDbContext _virtualDbContext; private readonly ShardingDefaultDbContext _virtualDbContext;
private readonly IShardingRouteManager _shardingRouteManager;
public ShardingTest(ShardingDefaultDbContext virtualDbContext) public ShardingTest(ShardingDefaultDbContext virtualDbContext,IShardingRouteManager shardingRouteManager)
{ {
_virtualDbContext = virtualDbContext; _virtualDbContext = virtualDbContext;
_shardingRouteManager = shardingRouteManager;
} }
//[Fact] //[Fact]
@ -38,6 +42,38 @@ namespace ShardingCore.Test50_2x
// Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count()); // Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count());
// Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail))); // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail)));
//} //}
[Fact]
public async Task ToList_All_Route_Test()
{
using (_shardingRouteManager.CreateScope())
{
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(333, mod00s.Count);
}
var mods = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(1000, mods.Count);
var modOrders1 = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
int ascAge = 1;
foreach (var sysUserMod in modOrders1)
{
Assert.Equal(ascAge, sysUserMod.Age);
ascAge++;
}
var modOrders2 = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToListAsync();
int descAge = 1000;
foreach (var sysUserMod in modOrders2)
{
Assert.Equal(descAge, sysUserMod.Age);
descAge--;
}
}
[Fact] [Fact]
public async Task ToList_All_Test() public async Task ToList_All_Test()
{ {

View File

@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Test50_3x.Domain.Entities; using ShardingCore.Test50_3x.Domain.Entities;
using Xunit; using Xunit;
@ -15,10 +17,12 @@ namespace ShardingCore.Test50_3x
public class ShardingTest public class ShardingTest
{ {
private readonly ShardingDefaultDbContext _virtualDbContext; private readonly ShardingDefaultDbContext _virtualDbContext;
private readonly IShardingRouteManager _shardingRouteManager;
public ShardingTest(ShardingDefaultDbContext virtualDbContext) public ShardingTest(ShardingDefaultDbContext virtualDbContext, IShardingRouteManager shardingRouteManager)
{ {
_virtualDbContext = virtualDbContext; _virtualDbContext = virtualDbContext;
_shardingRouteManager = shardingRouteManager;
} }
//[Fact] //[Fact]
@ -38,6 +42,38 @@ namespace ShardingCore.Test50_3x
// Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count()); // Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count());
// Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail))); // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail)));
//} //}
[Fact]
public async Task ToList_All_Route_Test()
{
using (_shardingRouteManager.CreateScope())
{
_shardingRouteManager.Current.Must.TryAdd(typeof(SysUserMod), new HashSet<string>() { "00" });
var mod00s = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(333, mod00s.Count);
}
var mods = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
Assert.Equal(1000, mods.Count);
var modOrders1 = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
int ascAge = 1;
foreach (var sysUserMod in modOrders1)
{
Assert.Equal(ascAge, sysUserMod.Age);
ascAge++;
}
var modOrders2 = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToListAsync();
int descAge = 1000;
foreach (var sysUserMod in modOrders2)
{
Assert.Equal(descAge, sysUserMod.Age);
descAge--;
}
}
[Fact] [Fact]
public async Task ToList_All_Test() public async Task ToList_All_Test()
{ {