更新文档添加金额表尝试针对join使用
This commit is contained in:
parent
ab43a0a117
commit
2bb8ce73a1
23
README.md
23
README.md
|
@ -223,6 +223,29 @@ AbstractSimpleShardingYearKeyLongVirtualRoute |按时间戳 |yyyy | `>,>=,<,<=,=
|
||||||
|
|
||||||
注:`contains`表示为`o=>ids.contains(o.shardingkey)`
|
注:`contains`表示为`o=>ids.contains(o.shardingkey)`
|
||||||
|
|
||||||
|
#高级
|
||||||
|
|
||||||
|
##批量操作
|
||||||
|
|
||||||
|
批量操作将对应的dbcontext和数据进行分离由用户自己选择第三方框架比如zzz进行批量操作或者batchextension
|
||||||
|
```c#
|
||||||
|
virtualDbContext.BulkInsert<SysUserMod>(new List<SysUserMod>())
|
||||||
|
.BatchGroups.ForEach(pair =>
|
||||||
|
{
|
||||||
|
///zzz or other
|
||||||
|
pair.Key.BlukInsert(pair.Value);
|
||||||
|
});
|
||||||
|
var shardingBatchUpdateEntry = virtualDbContext.BulkUpdate<SysUserMod>(o => o.Id == "1", o => new SysUserMod()
|
||||||
|
{
|
||||||
|
Name = "name_01"
|
||||||
|
});
|
||||||
|
shardingBatchUpdateEntry.DbContexts.ForEach(context =>
|
||||||
|
{
|
||||||
|
//zzz or other
|
||||||
|
context.Where(shardingBatchUpdateEntry.Where).Update(shardingBatchUpdateEntry.UpdateExp);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
# 最后
|
# 最后
|
||||||
凭借各大开源生态圈提供的优秀代码和思路才有的这个框架,希望可以为.Net生态提供一份微薄之力,该框架本人会一直长期维护,有大神技术支持可以联系下方方式欢迎star :)
|
凭借各大开源生态圈提供的优秀代码和思路才有的这个框架,希望可以为.Net生态提供一份微薄之力,该框架本人会一直长期维护,有大神技术支持可以联系下方方式欢迎star :)
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ namespace ShardingCore.Core.Internal.StreamMerge.GenericMerges
|
||||||
}
|
}
|
||||||
public async Task<List<TResult>> ExecuteAsync<TResult>(Func<IQueryable, Task<TResult>> efQuery)
|
public async Task<List<TResult>> ExecuteAsync<TResult>(Func<IQueryable, Task<TResult>> efQuery)
|
||||||
{
|
{
|
||||||
|
if (_mergeContext.Skip.HasValue || _mergeContext.Take.HasValue)
|
||||||
|
throw new InvalidOperationException("aggregate not support skip take");
|
||||||
//从各个分表获取数据
|
//从各个分表获取数据
|
||||||
List<DbContext> parallelDbContexts = new List<DbContext>(_mergeContext.RouteResults.Count());
|
List<DbContext> parallelDbContexts = new List<DbContext>(_mergeContext.RouteResults.Count());
|
||||||
try
|
try
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.Internal.Visitors.GroupBys
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 21:20:19
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class GroupByAggregateMethod
|
||||||
|
{
|
||||||
|
public GroupByAggregateMethod(string aggregateMethodName)
|
||||||
|
{
|
||||||
|
AggregateMethodName = aggregateMethodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
public string AggregateMethodName { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.Internal.Visitors.GroupBys
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 21:17:55
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class GroupByContext
|
||||||
|
{
|
||||||
|
|
||||||
|
public LambdaExpression GroupExpression { get; set; }
|
||||||
|
public List<GroupByAggregateMethod> GroupByAggregateMethods { get; set; } = new List<GroupByAggregateMethod>();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using ShardingCore.Core.Internal.Visitors.GroupBys;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.Internal.Visitors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 17:30:48
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class QueryAggregateDiscoverVisitor:ExpressionVisitor
|
||||||
|
{
|
||||||
|
public List<GroupByAggregateMethod> AggregateMethods { get; private set; } = new List<GroupByAggregateMethod>();
|
||||||
|
protected override Expression VisitMethodCall(MethodCallExpression node)
|
||||||
|
{
|
||||||
|
var method = node.Method;
|
||||||
|
if (method.Name == nameof(Queryable.Count)||method.Name == nameof(Queryable.Sum)||method.Name == nameof(Queryable.Max)||method.Name == nameof(Queryable.Min)||method.Name == nameof(Queryable.Average))
|
||||||
|
{
|
||||||
|
AggregateMethods.Add(new GroupByAggregateMethod(method.Name));
|
||||||
|
}
|
||||||
|
return base.VisitMethodCall(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using ShardingCore.Core.Internal.Visitors.GroupBys;
|
||||||
|
using ShardingCore.Extensions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.Internal.Visitors
|
namespace ShardingCore.Core.Internal.Visitors
|
||||||
{
|
{
|
||||||
|
@ -16,6 +18,8 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
private int? _skip;
|
private int? _skip;
|
||||||
private int? _take;
|
private int? _take;
|
||||||
private LinkedList<PropertyOrder> _orders = new LinkedList<PropertyOrder>();
|
private LinkedList<PropertyOrder> _orders = new LinkedList<PropertyOrder>();
|
||||||
|
private LinkedList<string> _groups = new LinkedList<string>();
|
||||||
|
private GroupByContext _groupByContext=new GroupByContext();
|
||||||
|
|
||||||
public int? GetSkip()
|
public int? GetSkip()
|
||||||
{
|
{
|
||||||
|
@ -76,6 +80,29 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
var propertyExpression=string.Join(".", properties);
|
var propertyExpression=string.Join(".", properties);
|
||||||
_orders.AddFirst(new PropertyOrder(propertyExpression,method.Name == nameof(Queryable.OrderBy)||method.Name == nameof(Queryable.ThenBy)));
|
_orders.AddFirst(new PropertyOrder(propertyExpression,method.Name == nameof(Queryable.OrderBy)||method.Name == nameof(Queryable.ThenBy)));
|
||||||
}
|
}
|
||||||
|
// else if (node.Method.Name == nameof(Queryable.GroupBy))
|
||||||
|
// {
|
||||||
|
// if (_groupByContext.GroupExpression == null)
|
||||||
|
// {
|
||||||
|
// var expression=(node.Arguments[1] as UnaryExpression).Operand as LambdaExpression;
|
||||||
|
// if (expression == null)
|
||||||
|
// throw new NotSupportedException("sharding group not support ");
|
||||||
|
// _groupByContext.GroupExpression = expression;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else if (node.Method.Name == nameof(Queryable.Select))
|
||||||
|
// {
|
||||||
|
// if (_groupByContext.GroupByAggregateMethods.IsEmpty())
|
||||||
|
// {
|
||||||
|
// var expression=((node.Arguments[1] as UnaryExpression).Operand as LambdaExpression).Body as NewExpression;
|
||||||
|
// if (expression != null)
|
||||||
|
// {
|
||||||
|
// var aggregateDiscoverVisitor = new QueryAggregateDiscoverVisitor();
|
||||||
|
// aggregateDiscoverVisitor.Visit(expression);
|
||||||
|
// _groupByContext.GroupByAggregateMethods = aggregateDiscoverVisitor.AggregateMethods;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return base.VisitMethodCall(node);
|
return base.VisitMethodCall(node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace ShardingCore.Test50.MySql.Domain.Entities
|
||||||
/// 用户姓名
|
/// 用户姓名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Age { get; set; }
|
public int Age { get; set; }
|
||||||
|
public int AgeGroup { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,27 +1,27 @@
|
||||||
using ShardingCore.Core;
|
// using ShardingCore.Core;
|
||||||
|
//
|
||||||
namespace ShardingCore.Test50.MySql.Domain.Entities
|
// namespace ShardingCore.Test50.MySql.Domain.Entities
|
||||||
{
|
// {
|
||||||
/*
|
// /*
|
||||||
* @Author: xjm
|
// * @Author: xjm
|
||||||
* @Description:
|
// * @Description:
|
||||||
* @Date: Wednesday, 20 January 2021 10:43:19
|
// * @Date: Wednesday, 20 January 2021 10:43:19
|
||||||
* @Email: 326308290@qq.com
|
// * @Email: 326308290@qq.com
|
||||||
*/
|
// */
|
||||||
public class SysUserRange:IShardingEntity
|
// public class SysUserRange:IShardingEntity
|
||||||
{
|
// {
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 分表分库range切分
|
// /// 分表分库range切分
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
[ShardingKey(TailPrefix = "_",AutoCreateTableOnStart = true)]
|
// [ShardingKey(TailPrefix = "_",AutoCreateTableOnStart = true)]
|
||||||
public string Id { get; set; }
|
// public string Id { get; set; }
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 姓名
|
// /// 姓名
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public string Name { get; set; }
|
// public string Name { get; set; }
|
||||||
/// <summary>
|
// /// <summary>
|
||||||
/// 年龄
|
// /// 年龄
|
||||||
/// </summary>
|
// /// </summary>
|
||||||
public int Age { get; set; }
|
// public int Age { get; set; }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using ShardingCore.Core;
|
||||||
|
|
||||||
|
namespace ShardingCore.Test50.MySql.Domain.Entities
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 15:40:46
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class SysUserSalary:IShardingEntity
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string UserId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 每月的金额
|
||||||
|
/// </summary>
|
||||||
|
[ShardingKey(AutoCreateTableOnStart = false)]
|
||||||
|
public int DateOfMonth { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 工资
|
||||||
|
/// </summary>
|
||||||
|
public int Salary { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,23 +1,23 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
// using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
// using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
using ShardingCore.Test50.MySql.Domain.Entities;
|
// using ShardingCore.Test50.MySql.Domain.Entities;
|
||||||
|
//
|
||||||
namespace ShardingCore.Test50.MySql.Domain.Maps
|
// namespace ShardingCore.Test50.MySql.Domain.Maps
|
||||||
{
|
// {
|
||||||
/*
|
// /*
|
||||||
* @Author: xjm
|
// * @Author: xjm
|
||||||
* @Description:
|
// * @Description:
|
||||||
* @Date: Wednesday, 20 January 2021 10:45:47
|
// * @Date: Wednesday, 20 January 2021 10:45:47
|
||||||
* @Email: 326308290@qq.com
|
// * @Email: 326308290@qq.com
|
||||||
*/
|
// */
|
||||||
public class SysUserRangeMap:IEntityTypeConfiguration<SysUserRange>
|
// public class SysUserRangeMap:IEntityTypeConfiguration<SysUserRange>
|
||||||
{
|
// {
|
||||||
public void Configure(EntityTypeBuilder<SysUserRange> builder)
|
// public void Configure(EntityTypeBuilder<SysUserRange> builder)
|
||||||
{
|
// {
|
||||||
builder.HasKey(o => o.Id);
|
// builder.HasKey(o => o.Id);
|
||||||
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
// builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
||||||
builder.Property(o => o.Name).HasMaxLength(128);
|
// builder.Property(o => o.Name).HasMaxLength(128);
|
||||||
builder.ToTable(nameof(SysUserRange));
|
// builder.ToTable(nameof(SysUserRange));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
using ShardingCore.Test50.MySql.Domain.Entities;
|
||||||
|
|
||||||
|
namespace ShardingCore.Test50.MySql.Domain.Maps
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 15:42:35
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class SysUserSalaryMap:IEntityTypeConfiguration<SysUserSalary>
|
||||||
|
{
|
||||||
|
public void Configure(EntityTypeBuilder<SysUserSalary> builder)
|
||||||
|
{
|
||||||
|
builder.HasKey(o => o.Id);
|
||||||
|
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
||||||
|
builder.Property(o => o.UserId).IsRequired().HasMaxLength(128);
|
||||||
|
builder.ToTable(nameof(SysUserSalary));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,15 +26,42 @@ namespace ShardingCore.Test50.MySql
|
||||||
public async Task ToList_All_Test()
|
public async Task ToList_All_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
|
||||||
Assert.Equal(100,mods.Count);
|
Assert.Equal(1000,mods.Count);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().ToShardingListAsync();
|
}
|
||||||
Assert.Equal(1000,ranges.Count);
|
[Fact]
|
||||||
|
public async Task ToList_Join_Test()
|
||||||
|
{
|
||||||
|
var list =await (from u in _virtualDbContext.Set<SysUserMod>()
|
||||||
|
join salary in _virtualDbContext.Set<SysUserSalary>()
|
||||||
|
on u.Id equals salary.UserId
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
Salary = salary.Salary,
|
||||||
|
DateOfMonth=salary.DateOfMonth,
|
||||||
|
Name = u.Name
|
||||||
|
}).ToShardingListAsync();
|
||||||
|
Assert.Equal(24000,list.Count());
|
||||||
|
Assert.Equal(24,list.Count(o => o.Name=="name_200"));
|
||||||
|
|
||||||
|
|
||||||
|
var queryable = (from u in _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="300")
|
||||||
|
join salary in _virtualDbContext.Set<SysUserSalary>()
|
||||||
|
on u.Id equals salary.UserId
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
Salary = salary.Salary,
|
||||||
|
DateOfMonth=salary.DateOfMonth,
|
||||||
|
Name = u.Name
|
||||||
|
});
|
||||||
|
var list1 = await queryable.ToShardingListAsync();
|
||||||
|
Assert.Equal(24,list1.Count());
|
||||||
|
Assert.DoesNotContain(list1,o=>o.Name!="name_300");
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_OrderBy_Asc_Desc_Test()
|
public async Task ToList_OrderBy_Asc_Desc_Test()
|
||||||
{
|
{
|
||||||
var modascs=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ToShardingListAsync();
|
var modascs=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ToShardingListAsync();
|
||||||
Assert.Equal(100,modascs.Count);
|
Assert.Equal(1000,modascs.Count);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
foreach (var age in modascs)
|
foreach (var age in modascs)
|
||||||
{
|
{
|
||||||
|
@ -43,13 +70,12 @@ namespace ShardingCore.Test50.MySql
|
||||||
|
|
||||||
}
|
}
|
||||||
var moddescs=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ToShardingListAsync();
|
var moddescs=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ToShardingListAsync();
|
||||||
Assert.Equal(100,moddescs.Count);
|
Assert.Equal(1000,moddescs.Count);
|
||||||
var j = 100;
|
var j = 1000;
|
||||||
foreach (var age in moddescs)
|
foreach (var age in moddescs)
|
||||||
{
|
{
|
||||||
Assert.Equal(j,age.Age);
|
Assert.Equal(j,age.Age);
|
||||||
j--;
|
j--;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -57,14 +83,11 @@ namespace ShardingCore.Test50.MySql
|
||||||
{
|
{
|
||||||
var ids = new[] {"1", "2", "3", "4"};
|
var ids = new[] {"1", "2", "3", "4"};
|
||||||
var sysUserMods=await _virtualDbContext.Set<SysUserMod>().Where(o=>ids.Contains(o.Id)).ToShardingListAsync();
|
var sysUserMods=await _virtualDbContext.Set<SysUserMod>().Where(o=>ids.Contains(o.Id)).ToShardingListAsync();
|
||||||
var sysUserRanges=await _virtualDbContext.Set<SysUserRange>().Where(o=>ids.Contains(o.Id)).ToShardingListAsync();
|
|
||||||
foreach (var id in ids)
|
foreach (var id in ids)
|
||||||
{
|
{
|
||||||
Assert.Contains(sysUserMods, o =>o.Id==id);
|
Assert.Contains(sysUserMods, o =>o.Id==id);
|
||||||
Assert.Contains(sysUserRanges, o =>o.Id==id);
|
|
||||||
}
|
}
|
||||||
Assert.DoesNotContain(sysUserMods,o=>o.Age>4);
|
Assert.DoesNotContain(sysUserMods,o=>o.Age>4);
|
||||||
Assert.DoesNotContain(sysUserRanges,o=>o.Age>4);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Eq_Test()
|
public async Task ToList_Id_Eq_Test()
|
||||||
|
@ -72,34 +95,28 @@ namespace ShardingCore.Test50.MySql
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="3").ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="3").ToShardingListAsync();
|
||||||
Assert.Single(mods);
|
Assert.Single(mods);
|
||||||
Assert.Equal("3",mods[0].Id);
|
Assert.Equal("3",mods[0].Id);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="3").ToShardingListAsync();
|
|
||||||
Assert.Single(ranges);
|
|
||||||
Assert.Equal("3",ranges[0].Id);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Not_Eq_Test()
|
public async Task ToList_Id_Not_Eq_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").ToShardingListAsync();
|
||||||
Assert.Equal(99,mods.Count);
|
Assert.Equal(999,mods.Count);
|
||||||
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id!="3").ToShardingListAsync();
|
|
||||||
Assert.Equal(999,ranges.Count);
|
|
||||||
Assert.DoesNotContain(ranges,o=>o.Id=="3");
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Not_Eq_Skip_Test()
|
public async Task ToList_Id_Not_Eq_Skip_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").OrderBy(o=>o.Age).Skip(2).ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").OrderBy(o=>o.Age).Skip(2).ToShardingListAsync();
|
||||||
Assert.Equal(97,mods.Count);
|
Assert.Equal(997,mods.Count);
|
||||||
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
||||||
Assert.Equal(4,mods[0].Age);
|
Assert.Equal(4,mods[0].Age);
|
||||||
Assert.Equal(5,mods[1].Age);
|
Assert.Equal(5,mods[1].Age);
|
||||||
|
|
||||||
var modsDesc=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").OrderByDescending(o=>o.Age).Skip(13).ToShardingListAsync();
|
var modsDesc=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").OrderByDescending(o=>o.Age).Skip(13).ToShardingListAsync();
|
||||||
Assert.Equal(86,modsDesc.Count);
|
Assert.Equal(986,modsDesc.Count);
|
||||||
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
||||||
Assert.Equal(87,modsDesc[0].Age);
|
Assert.Equal(987,modsDesc[0].Age);
|
||||||
Assert.Equal(86,modsDesc[1].Age);
|
Assert.Equal(986,modsDesc[1].Age);
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Name_Eq_Test()
|
public async Task ToList_Name_Eq_Test()
|
||||||
|
@ -107,25 +124,18 @@ namespace ShardingCore.Test50.MySql
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_3").ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_3").ToShardingListAsync();
|
||||||
Assert.Single(mods);
|
Assert.Single(mods);
|
||||||
Assert.Equal("3",mods[0].Id);
|
Assert.Equal("3",mods[0].Id);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_3").ToShardingListAsync();
|
|
||||||
Assert.Single(ranges);
|
|
||||||
Assert.Equal("3",ranges[0].Id);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Eq_Not_In_Db_Test()
|
public async Task ToList_Id_Eq_Not_In_Db_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1001").ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1001").ToShardingListAsync();
|
||||||
Assert.Empty(mods);
|
Assert.Empty(mods);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1001").ToShardingListAsync();
|
|
||||||
Assert.Empty(ranges);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Name_Eq_Not_In_Db_Test()
|
public async Task ToList_Name_Eq_Not_In_Db_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_1001").ToShardingListAsync();
|
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_1001").ToShardingListAsync();
|
||||||
Assert.Empty(mods);
|
Assert.Empty(mods);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ToShardingListAsync();
|
|
||||||
Assert.Empty(ranges);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault_Order_By_Id_Test()
|
public async Task FirstOrDefault_Order_By_Id_Test()
|
||||||
|
@ -133,22 +143,19 @@ namespace ShardingCore.Test50.MySql
|
||||||
var sysUserModAge=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ShardingFirstOrDefaultAsync();
|
var sysUserModAge=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserModAge!=null&&sysUserModAge.Id=="1");
|
Assert.True(sysUserModAge!=null&&sysUserModAge.Id=="1");
|
||||||
var sysUserModAgeDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ShardingFirstOrDefaultAsync();
|
var sysUserModAgeDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserModAgeDesc!=null&&sysUserModAgeDesc.Id=="100");
|
Assert.True(sysUserModAgeDesc!=null&&sysUserModAgeDesc.Id=="1000");
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
|
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
|
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
|
||||||
|
|
||||||
var sysUserModDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Id).ShardingFirstOrDefaultAsync();
|
var sysUserModDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Id).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserModDesc!=null&&sysUserModDesc.Id=="99");
|
Assert.True(sysUserModDesc!=null&&sysUserModDesc.Id=="999");
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault2()
|
public async Task FirstOrDefault2()
|
||||||
{
|
{
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
|
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
|
Assert.NotNull(sysUserMod);
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
|
Assert.True(sysUserMod.Id=="1");
|
||||||
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault3()
|
public async Task FirstOrDefault3()
|
||||||
|
@ -156,9 +163,6 @@ namespace ShardingCore.Test50.MySql
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_2").ShardingFirstOrDefaultAsync();
|
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_2").ShardingFirstOrDefaultAsync();
|
||||||
Assert.NotNull(sysUserMod);
|
Assert.NotNull(sysUserMod);
|
||||||
Assert.Equal("2",sysUserMod.Id);
|
Assert.Equal("2",sysUserMod.Id);
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_2").ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.NotNull(sysUserRange);
|
|
||||||
Assert.Equal("2",sysUserRange.Id);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault4()
|
public async Task FirstOrDefault4()
|
||||||
|
@ -166,25 +170,98 @@ namespace ShardingCore.Test50.MySql
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
|
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
|
||||||
Assert.NotNull(sysUserMod);
|
Assert.NotNull(sysUserMod);
|
||||||
Assert.True(sysUserMod.Id!="1");
|
Assert.True(sysUserMod.Id!="1");
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.NotNull(sysUserRange);
|
|
||||||
Assert.True(sysUserRange.Id!="1");
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault5()
|
public async Task FirstOrDefault5()
|
||||||
{
|
{
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_101").ShardingFirstOrDefaultAsync();
|
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_1001").ShardingFirstOrDefaultAsync();
|
||||||
Assert.Null(sysUserMod);
|
Assert.Null(sysUserMod);
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.Null(sysUserRange);
|
|
||||||
}
|
}
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Count_Test()
|
public async Task Count_Test()
|
||||||
{
|
{
|
||||||
var a=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_100").ShardingCountAsync();
|
var a=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_1000").ShardingCountAsync();
|
||||||
Assert.Equal(1,a);
|
Assert.Equal(1,a);
|
||||||
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_100").ShardingCountAsync();
|
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_1000").ShardingCountAsync();
|
||||||
Assert.Equal(99,b);
|
Assert.Equal(999,b);
|
||||||
}
|
}
|
||||||
|
[Fact]
|
||||||
|
public async Task Sum_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingSumAsync(o => o.Age);
|
||||||
|
var expected = 0;
|
||||||
|
for (int i = 1; i <= 1000; i++)
|
||||||
|
{
|
||||||
|
expected += i;
|
||||||
|
}
|
||||||
|
Assert.Equal(expected,a);
|
||||||
|
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_1000").ShardingSumAsync(o => o.Age);
|
||||||
|
Assert.Equal(expected-1000,b);
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public async Task Max_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(1000,a);
|
||||||
|
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_1000").ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(999,b);
|
||||||
|
var c=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age<500).ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(499,c);
|
||||||
|
var e=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age<=500).ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(500,e);
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public async Task Max_Join_Test()
|
||||||
|
{
|
||||||
|
var queryable = (from u in _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="300")
|
||||||
|
join salary in _virtualDbContext.Set<SysUserSalary>()
|
||||||
|
on u.Id equals salary.UserId
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
Salary = salary.Salary,
|
||||||
|
DateOfMonth=salary.DateOfMonth,
|
||||||
|
Name = u.Name
|
||||||
|
});
|
||||||
|
var maxSalary = await queryable.ShardingMaxAsync(o => o.Salary);
|
||||||
|
Assert.Equal(1390000,maxSalary);
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public async Task Min_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(1,a);
|
||||||
|
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_1").ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(2,b);
|
||||||
|
var c=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age>500).ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(501,c);
|
||||||
|
var e=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age>=500).ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(500,e);
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public async Task Any_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => o.Age==100);
|
||||||
|
Assert.True(a);
|
||||||
|
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_1").ShardingAnyAsync(o => o.Age==1);
|
||||||
|
Assert.False(b);
|
||||||
|
var c=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age>500).ShardingAnyAsync(o => o.Age<=500);
|
||||||
|
Assert.False(c);
|
||||||
|
var e=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age>=500).ShardingAnyAsync(o => o.Age<=500);
|
||||||
|
Assert.True(e);
|
||||||
|
}
|
||||||
|
// [Fact]
|
||||||
|
// public async Task Group_Test()
|
||||||
|
// {
|
||||||
|
// var ids = new[] {"200", "300"};
|
||||||
|
// var x=await (from u in _virtualDbContext.Set<SysUserSalary>().Where(o=>ids.Contains(o.Id))
|
||||||
|
// group u by u.UserId into g
|
||||||
|
// select new
|
||||||
|
// {
|
||||||
|
// AgeGroup=g.Key,
|
||||||
|
// Count=g.Count(),
|
||||||
|
// TotalSalary=g.Sum(o=>o.Salary)
|
||||||
|
// }).ToShardingListAsync();
|
||||||
|
// var b = x;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,70 +1,70 @@
|
||||||
using System;
|
// using System;
|
||||||
using System.Collections.Generic;
|
// using System.Collections.Generic;
|
||||||
using System.Linq.Expressions;
|
// using System.Linq.Expressions;
|
||||||
using ShardingCore.Core.VirtualRoutes;
|
// using ShardingCore.Core.VirtualRoutes;
|
||||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
// using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||||
using ShardingCore.Helpers;
|
// using ShardingCore.Helpers;
|
||||||
using ShardingCore.Test50.MySql.Domain.Entities;
|
// using ShardingCore.Test50.MySql.Domain.Entities;
|
||||||
|
//
|
||||||
namespace ShardingCore.Test50.MySql.Shardings
|
// namespace ShardingCore.Test50.MySql.Shardings
|
||||||
{
|
// {
|
||||||
/*
|
// /*
|
||||||
* @Author: xjm
|
// * @Author: xjm
|
||||||
* @Description:
|
// * @Description:
|
||||||
* @Date: Wednesday, 20 January 2021 10:46:37
|
// * @Date: Wednesday, 20 January 2021 10:46:37
|
||||||
* @Email: 326308290@qq.com
|
// * @Email: 326308290@qq.com
|
||||||
*/
|
// */
|
||||||
public class SysUserRangeVirtualRoute: AbstractShardingOperatorVirtualRoute<SysUserRange, string>
|
// public class SysUserRangeVirtualRoute: AbstractShardingOperatorVirtualRoute<SysUserRange, string>
|
||||||
{
|
// {
|
||||||
private int _mod = 1000;
|
// private int _mod = 1000;
|
||||||
protected override string ConvertToShardingKey(object shardingKey)
|
// protected override string ConvertToShardingKey(object shardingKey)
|
||||||
{
|
// {
|
||||||
return shardingKey.ToString();
|
// return shardingKey.ToString();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override string ShardingKeyToTail(object shardingKey)
|
// public override string ShardingKeyToTail(object shardingKey)
|
||||||
{
|
// {
|
||||||
var shardingKeyStr = ConvertToShardingKey(shardingKey);
|
// var shardingKeyStr = ConvertToShardingKey(shardingKey);
|
||||||
var m = Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % _mod);
|
// var m = Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % _mod);
|
||||||
if (m > 800)//801-999
|
// if (m > 800)//801-999
|
||||||
{
|
// {
|
||||||
return "3";
|
// return "3";
|
||||||
} else if (m > 600)//601-800
|
// } else if (m > 600)//601-800
|
||||||
{
|
// {
|
||||||
return "2";
|
// return "2";
|
||||||
} else if (m > 300)//301-600
|
// } else if (m > 300)//301-600
|
||||||
{
|
// {
|
||||||
return "1";
|
// return "1";
|
||||||
} else //0-300
|
// } else //0-300
|
||||||
{
|
// {
|
||||||
return "0";
|
// return "0";
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public override List<string> GetAllTails()
|
// public override List<string> GetAllTails()
|
||||||
{
|
// {
|
||||||
return new(){"0", "1","2","3"};
|
// return new(){"0", "1","2","3"};
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
// protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
{
|
// {
|
||||||
var t = ShardingKeyToTail(shardingKey);
|
// var t = ShardingKeyToTail(shardingKey);
|
||||||
switch (shardingOperator)
|
// switch (shardingOperator)
|
||||||
{
|
// {
|
||||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
// case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||||
default:
|
// default:
|
||||||
{
|
// {
|
||||||
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
// Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||||
return tail => true;
|
// return tail => true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// public override List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
// // public override List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
||||||
// {
|
// // {
|
||||||
// if (filterPhysicTables.Count > 1)
|
// // if (filterPhysicTables.Count > 1)
|
||||||
// throw new Exception($"query {nameof(SysUserRange)} not support cross table");
|
// // throw new Exception($"query {nameof(SysUserRange)} not support cross table");
|
||||||
// return base.AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
|
// // return base.AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
|
||||||
// }
|
// // }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
|
@ -0,0 +1,74 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using ShardingCore.Core.VirtualRoutes;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||||
|
using ShardingCore.Test50.MySql.Domain.Entities;
|
||||||
|
|
||||||
|
namespace ShardingCore.Test50.MySql.Shardings
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 15:54:55
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class SysUserSalaryVirtualRoute:AbstractShardingOperatorVirtualRoute<SysUserSalary,int>
|
||||||
|
{
|
||||||
|
protected override int ConvertToShardingKey(object shardingKey)
|
||||||
|
{
|
||||||
|
return Convert.ToInt32(shardingKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ShardingKeyToTail(object shardingKey)
|
||||||
|
{
|
||||||
|
var time = ConvertToShardingKey(shardingKey);
|
||||||
|
return TimeFormatToTail(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override List<string> GetAllTails()
|
||||||
|
{
|
||||||
|
var beginTime = new DateTime(2020, 1, 1);
|
||||||
|
var endTime = new DateTime(2021, 12, 1);
|
||||||
|
var list = new List<string>(24);
|
||||||
|
var tempTime = beginTime;
|
||||||
|
while (tempTime <= endTime)
|
||||||
|
{
|
||||||
|
list.Add($"{tempTime:yyyyMM}");
|
||||||
|
tempTime = tempTime.AddMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string TimeFormatToTail(int time)
|
||||||
|
{
|
||||||
|
var dateOfMonth=DateTime.ParseExact($"{time}","yyyyMM",System.Globalization.CultureInfo.InvariantCulture,System.Globalization.DateTimeStyles.AdjustToUniversal);
|
||||||
|
return $"{dateOfMonth:yyyyMM}";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression<Func<string, bool>> GetRouteToFilter(int shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
|
{
|
||||||
|
var t = TimeFormatToTail(shardingKey);
|
||||||
|
switch (shardingOperator)
|
||||||
|
{
|
||||||
|
case ShardingOperatorEnum.GreaterThan:
|
||||||
|
case ShardingOperatorEnum.GreaterThanOrEqual:
|
||||||
|
return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
||||||
|
case ShardingOperatorEnum.LessThan:
|
||||||
|
return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
||||||
|
case ShardingOperatorEnum.LessThanOrEqual:
|
||||||
|
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||||
|
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||||
|
#endif
|
||||||
|
return tail => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,7 +44,7 @@ namespace ShardingCore.Test50.MySql
|
||||||
o.ConnectionString = hostBuilderContext.Configuration.GetSection("MySql")["ConnectionString"];
|
o.ConnectionString = hostBuilderContext.Configuration.GetSection("MySql")["ConnectionString"];
|
||||||
o.ServerVersion = new MySqlServerVersion(new Version());
|
o.ServerVersion = new MySqlServerVersion(new Version());
|
||||||
o.AddSharding<SysUserModVirtualRoute>();
|
o.AddSharding<SysUserModVirtualRoute>();
|
||||||
o.AddSharding<SysUserRangeVirtualRoute>();
|
o.AddSharding<SysUserSalaryVirtualRoute>();
|
||||||
o.CreateIfNotExists((provider, config) =>
|
o.CreateIfNotExists((provider, config) =>
|
||||||
{
|
{
|
||||||
config.EnsureCreated = true;
|
config.EnsureCreated = true;
|
||||||
|
@ -73,34 +73,41 @@ namespace ShardingCore.Test50.MySql
|
||||||
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
|
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
|
||||||
if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => true))
|
if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => true))
|
||||||
{
|
{
|
||||||
var ids = Enumerable.Range(1, 100);
|
var ids = Enumerable.Range(1, 1000);
|
||||||
var userMods = new List<SysUserMod>();
|
var userMods = new List<SysUserMod>();
|
||||||
|
var userSalaries = new List<SysUserSalary>();
|
||||||
|
var beginTime = new DateTime(2020, 1, 1);
|
||||||
|
var endTime = new DateTime(2021, 12, 1);
|
||||||
foreach (var id in ids)
|
foreach (var id in ids)
|
||||||
{
|
{
|
||||||
userMods.Add(new SysUserMod()
|
userMods.Add(new SysUserMod()
|
||||||
{
|
{
|
||||||
Id = id.ToString(),
|
Id = id.ToString(),
|
||||||
Age = id,
|
Age = id,
|
||||||
Name = $"name_{id}"
|
Name = $"name_{id}",
|
||||||
|
AgeGroup=Math.Abs(id%10)
|
||||||
});
|
});
|
||||||
|
var tempTime = beginTime;
|
||||||
|
var i = 0;
|
||||||
|
while (tempTime<=endTime)
|
||||||
|
{
|
||||||
|
var dateOfMonth = $@"{tempTime:yyyyMM}";
|
||||||
|
userSalaries.Add(new SysUserSalary()
|
||||||
|
{
|
||||||
|
Id = $@"{id}{dateOfMonth}",
|
||||||
|
UserId = id.ToString(),
|
||||||
|
DateOfMonth = int.Parse(dateOfMonth),
|
||||||
|
Salary = 700000+id*100*i
|
||||||
|
});
|
||||||
|
tempTime=tempTime.AddMonths(1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await virtualDbContext.InsertRangeAsync(userMods);
|
await virtualDbContext.InsertRangeAsync(userMods);
|
||||||
|
await virtualDbContext.InsertRangeAsync(userSalaries);
|
||||||
|
|
||||||
|
|
||||||
var idRanges = Enumerable.Range(1, 1000);
|
|
||||||
var userRanges = new List<SysUserRange>();
|
|
||||||
foreach (var id in idRanges)
|
|
||||||
{
|
|
||||||
userRanges.Add(new SysUserRange()
|
|
||||||
{
|
|
||||||
Id = id.ToString(),
|
|
||||||
Age = id,
|
|
||||||
Name = $"name_range_{id}"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await virtualDbContext.InsertRangeAsync(userRanges);
|
|
||||||
await virtualDbContext.SaveChangesAsync();
|
await virtualDbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace ShardingCore.Test50.Domain.Entities
|
||||||
/// 用户姓名
|
/// 用户姓名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Age { get; set; }
|
public int Age { get; set; }
|
||||||
|
public int AgeGroup { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
using ShardingCore.Core;
|
|
||||||
|
|
||||||
namespace ShardingCore.Test50.Domain.Entities
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Wednesday, 20 January 2021 10:43:19
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserRange:IShardingEntity
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 分表分库range切分
|
|
||||||
/// </summary>
|
|
||||||
[ShardingKey(TailPrefix = "_",AutoCreateTableOnStart = true)]
|
|
||||||
public string Id { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 姓名
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 年龄
|
|
||||||
/// </summary>
|
|
||||||
public int Age { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
using System;
|
||||||
|
using ShardingCore.Core;
|
||||||
|
|
||||||
|
namespace ShardingCore.Test50.Domain.Entities
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 15:43:22
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class SysUserSalary:IShardingEntity
|
||||||
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
public string UserId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 每月的金额
|
||||||
|
/// </summary>
|
||||||
|
[ShardingKey(AutoCreateTableOnStart = true)]
|
||||||
|
public int DateOfMonth { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 工资
|
||||||
|
/// </summary>
|
||||||
|
public int Salary { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +0,0 @@
|
||||||
namespace ShardingCore.Test50.Domain.Entities
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Friday, 22 January 2021 14:17:29
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class UserGroup
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,17 +7,17 @@ namespace ShardingCore.Test50.Domain.Maps
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Wednesday, 20 January 2021 10:45:47
|
* @Date: Monday, 01 February 2021 15:42:35
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public class SysUserRangeMap:IEntityTypeConfiguration<SysUserRange>
|
public class SysUserSalaryMap:IEntityTypeConfiguration<SysUserSalary>
|
||||||
{
|
{
|
||||||
public void Configure(EntityTypeBuilder<SysUserRange> builder)
|
public void Configure(EntityTypeBuilder<SysUserSalary> builder)
|
||||||
{
|
{
|
||||||
builder.HasKey(o => o.Id);
|
builder.HasKey(o => o.Id);
|
||||||
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
||||||
builder.Property(o => o.Name).HasMaxLength(128);
|
builder.Property(o => o.UserId).IsRequired().HasMaxLength(128);
|
||||||
builder.ToTable(nameof(SysUserRange));
|
builder.ToTable(nameof(SysUserSalary));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,166 +25,219 @@ namespace ShardingCore.Test50
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_All_Test()
|
public async Task ToList_All_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
|
||||||
Assert.Equal(100,mods.Count);
|
Assert.Equal(1000, mods.Count);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().ToShardingListAsync();
|
|
||||||
Assert.Equal(1000,ranges.Count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_OrderBy_Asc_Desc_Test()
|
public async Task ToList_OrderBy_Asc_Desc_Test()
|
||||||
{
|
{
|
||||||
var modascs=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ToShardingListAsync();
|
var modascs = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToShardingListAsync();
|
||||||
Assert.Equal(100,modascs.Count);
|
Assert.Equal(1000, modascs.Count);
|
||||||
var i = 1;
|
var i = 1;
|
||||||
foreach (var age in modascs)
|
foreach (var age in modascs)
|
||||||
{
|
{
|
||||||
Assert.Equal(i,age.Age);
|
Assert.Equal(i, age.Age);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
}
|
}
|
||||||
var moddescs=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ToShardingListAsync();
|
|
||||||
Assert.Equal(100,moddescs.Count);
|
var moddescs = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToShardingListAsync();
|
||||||
var j = 100;
|
Assert.Equal(1000, moddescs.Count);
|
||||||
|
var j = 1000;
|
||||||
foreach (var age in moddescs)
|
foreach (var age in moddescs)
|
||||||
{
|
{
|
||||||
Assert.Equal(j,age.Age);
|
Assert.Equal(j, age.Age);
|
||||||
j--;
|
j--;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_In_Test()
|
public async Task ToList_Id_In_Test()
|
||||||
{
|
{
|
||||||
var ids = new[] {"1", "2", "3", "4"};
|
var ids = new[] {"1", "2", "3", "4"};
|
||||||
var sysUserMods=await _virtualDbContext.Set<SysUserMod>().Where(o=>ids.Contains(o.Id)).ToShardingListAsync();
|
var sysUserMods = await _virtualDbContext.Set<SysUserMod>().Where(o => ids.Contains(o.Id)).ToShardingListAsync();
|
||||||
var sysUserRanges=await _virtualDbContext.Set<SysUserRange>().Where(o=>ids.Contains(o.Id)).ToShardingListAsync();
|
|
||||||
foreach (var id in ids)
|
foreach (var id in ids)
|
||||||
{
|
{
|
||||||
Assert.Contains(sysUserMods, o =>o.Id==id);
|
Assert.Contains(sysUserMods, o => o.Id == id);
|
||||||
Assert.Contains(sysUserRanges, o =>o.Id==id);
|
|
||||||
}
|
}
|
||||||
Assert.DoesNotContain(sysUserMods,o=>o.Age>4);
|
|
||||||
Assert.DoesNotContain(sysUserRanges,o=>o.Age>4);
|
Assert.DoesNotContain(sysUserMods, o => o.Age > 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Eq_Test()
|
public async Task ToList_Id_Eq_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="3").ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "3").ToShardingListAsync();
|
||||||
Assert.Single(mods);
|
Assert.Single(mods);
|
||||||
Assert.Equal("3",mods[0].Id);
|
Assert.Equal("3", mods[0].Id);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="3").ToShardingListAsync();
|
|
||||||
Assert.Single(ranges);
|
|
||||||
Assert.Equal("3",ranges[0].Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Not_Eq_Test()
|
public async Task ToList_Id_Not_Eq_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").ToShardingListAsync();
|
||||||
Assert.Equal(99,mods.Count);
|
Assert.Equal(999, mods.Count);
|
||||||
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
Assert.DoesNotContain(mods, o => o.Id == "3");
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id!="3").ToShardingListAsync();
|
|
||||||
Assert.Equal(999,ranges.Count);
|
|
||||||
Assert.DoesNotContain(ranges,o=>o.Id=="3");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Not_Eq_Skip_Test()
|
public async Task ToList_Id_Not_Eq_Skip_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").OrderBy(o=>o.Age).Skip(2).ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").OrderBy(o => o.Age).Skip(2).ToShardingListAsync();
|
||||||
Assert.Equal(97,mods.Count);
|
Assert.Equal(997, mods.Count);
|
||||||
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
Assert.DoesNotContain(mods, o => o.Id == "3");
|
||||||
Assert.Equal(4,mods[0].Age);
|
Assert.Equal(4, mods[0].Age);
|
||||||
Assert.Equal(5,mods[1].Age);
|
Assert.Equal(5, mods[1].Age);
|
||||||
|
|
||||||
var modsDesc=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").OrderByDescending(o=>o.Age).Skip(13).ToShardingListAsync();
|
var modsDesc = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").OrderByDescending(o => o.Age).Skip(13).ToShardingListAsync();
|
||||||
Assert.Equal(86,modsDesc.Count);
|
Assert.Equal(986, modsDesc.Count);
|
||||||
Assert.DoesNotContain(mods,o=>o.Id=="3");
|
Assert.DoesNotContain(mods, o => o.Id == "3");
|
||||||
Assert.Equal(87,modsDesc[0].Age);
|
Assert.Equal(987, modsDesc[0].Age);
|
||||||
Assert.Equal(86,modsDesc[1].Age);
|
Assert.Equal(986, modsDesc[1].Age);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Name_Eq_Test()
|
public async Task ToList_Name_Eq_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_3").ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_3").ToShardingListAsync();
|
||||||
Assert.Single(mods);
|
Assert.Single(mods);
|
||||||
Assert.Equal("3",mods[0].Id);
|
Assert.Equal("3", mods[0].Id);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_3").ToShardingListAsync();
|
|
||||||
Assert.Single(ranges);
|
|
||||||
Assert.Equal("3",ranges[0].Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Id_Eq_Not_In_Db_Test()
|
public async Task ToList_Id_Eq_Not_In_Db_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1001").ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "1001").ToShardingListAsync();
|
||||||
Assert.Empty(mods);
|
Assert.Empty(mods);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1001").ToShardingListAsync();
|
|
||||||
Assert.Empty(ranges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ToList_Name_Eq_Not_In_Db_Test()
|
public async Task ToList_Name_Eq_Not_In_Db_Test()
|
||||||
{
|
{
|
||||||
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_1001").ToShardingListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1001").ToShardingListAsync();
|
||||||
Assert.Empty(mods);
|
Assert.Empty(mods);
|
||||||
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ToShardingListAsync();
|
|
||||||
Assert.Empty(ranges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault_Order_By_Id_Test()
|
public async Task FirstOrDefault_Order_By_Id_Test()
|
||||||
{
|
{
|
||||||
var sysUserModAge=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ShardingFirstOrDefaultAsync();
|
var sysUserModAge = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserModAge!=null&&sysUserModAge.Id=="1");
|
Assert.True(sysUserModAge != null && sysUserModAge.Id == "1");
|
||||||
var sysUserModAgeDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ShardingFirstOrDefaultAsync();
|
var sysUserModAgeDesc = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserModAgeDesc!=null&&sysUserModAgeDesc.Id=="100");
|
Assert.True(sysUserModAgeDesc != null && sysUserModAgeDesc.Id == "1000");
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
|
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Id).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
|
Assert.True(sysUserMod != null && sysUserMod.Id == "1");
|
||||||
|
|
||||||
var sysUserModDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Id).ShardingFirstOrDefaultAsync();
|
var sysUserModDesc = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Id).ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserModDesc!=null&&sysUserModDesc.Id=="99");
|
Assert.True(sysUserModDesc != null && sysUserModDesc.Id == "999");
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault2()
|
public async Task FirstOrDefault2()
|
||||||
{
|
{
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
|
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "1").ShardingFirstOrDefaultAsync();
|
||||||
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
|
Assert.NotNull(sysUserMod);
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
|
Assert.True(sysUserMod.Id == "1");
|
||||||
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault3()
|
public async Task FirstOrDefault3()
|
||||||
{
|
{
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_2").ShardingFirstOrDefaultAsync();
|
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_2").ShardingFirstOrDefaultAsync();
|
||||||
Assert.NotNull(sysUserMod);
|
Assert.NotNull(sysUserMod);
|
||||||
Assert.Equal("2",sysUserMod.Id);
|
Assert.Equal("2", sysUserMod.Id);
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_2").ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.NotNull(sysUserRange);
|
|
||||||
Assert.Equal("2",sysUserRange.Id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault4()
|
public async Task FirstOrDefault4()
|
||||||
{
|
{
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
|
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "1").ShardingFirstOrDefaultAsync();
|
||||||
Assert.NotNull(sysUserMod);
|
Assert.NotNull(sysUserMod);
|
||||||
Assert.True(sysUserMod.Id!="1");
|
Assert.True(sysUserMod.Id != "1");
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.NotNull(sysUserRange);
|
|
||||||
Assert.True(sysUserRange.Id!="1");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FirstOrDefault5()
|
public async Task FirstOrDefault5()
|
||||||
{
|
{
|
||||||
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_101").ShardingFirstOrDefaultAsync();
|
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1001").ShardingFirstOrDefaultAsync();
|
||||||
Assert.Null(sysUserMod);
|
Assert.Null(sysUserMod);
|
||||||
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ShardingFirstOrDefaultAsync();
|
|
||||||
Assert.Null(sysUserRange);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Count_Test()
|
public async Task Count_Test()
|
||||||
{
|
{
|
||||||
var a=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_100").ShardingCountAsync();
|
var a = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1000").ShardingCountAsync();
|
||||||
Assert.Equal(1,a);
|
Assert.Equal(1, a);
|
||||||
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_100").ShardingCountAsync();
|
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1000").ShardingCountAsync();
|
||||||
Assert.Equal(99,b);
|
Assert.Equal(999, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Sum_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingSumAsync(o => o.Age);
|
||||||
|
var expected = 0;
|
||||||
|
for (int i = 1; i <= 1000; i++)
|
||||||
|
{
|
||||||
|
expected += i;
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.Equal(expected, a);
|
||||||
|
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1000").ShardingSumAsync(o => o.Age);
|
||||||
|
Assert.Equal(expected - 1000, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Max_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(1000, a);
|
||||||
|
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1000").ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(999, b);
|
||||||
|
var c = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age < 500).ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(499, c);
|
||||||
|
var e = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age <= 500).ShardingMaxAsync(o => o.Age);
|
||||||
|
Assert.Equal(500, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Min_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(1, a);
|
||||||
|
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1").ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(2, b);
|
||||||
|
var c = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age > 500).ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(501, c);
|
||||||
|
var e = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age >= 500).ShardingMinAsync(o => o.Age);
|
||||||
|
Assert.Equal(500, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Any_Test()
|
||||||
|
{
|
||||||
|
var a = await _virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => o.Age == 100);
|
||||||
|
Assert.True(a);
|
||||||
|
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1").ShardingAnyAsync(o => o.Age == 1);
|
||||||
|
Assert.False(b);
|
||||||
|
var c = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age > 500).ShardingAnyAsync(o => o.Age <= 500);
|
||||||
|
Assert.False(c);
|
||||||
|
var e = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Age >= 500).ShardingAnyAsync(o => o.Age <= 500);
|
||||||
|
Assert.True(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [Fact]
|
||||||
|
// public async Task Group_Test()
|
||||||
|
// {
|
||||||
|
// var x = await (from u in _virtualDbContext.Set<SysUserMod>()
|
||||||
|
// group u by u.AgeGroup
|
||||||
|
// into g
|
||||||
|
// select new
|
||||||
|
// {
|
||||||
|
// AgeGroup = g.Key,
|
||||||
|
// Count = g.Count()
|
||||||
|
// }).ToShardingListAsync();
|
||||||
|
// var y = x;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,70 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using ShardingCore.Core.VirtualRoutes;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
|
||||||
using ShardingCore.Helpers;
|
|
||||||
using ShardingCore.Test50.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCore.Test50.Shardings
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Wednesday, 20 January 2021 10:46:37
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserRangeVirtualRoute: AbstractShardingOperatorVirtualRoute<SysUserRange, string>
|
|
||||||
{
|
|
||||||
private int _mod = 1000;
|
|
||||||
protected override string ConvertToShardingKey(object shardingKey)
|
|
||||||
{
|
|
||||||
return shardingKey.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ShardingKeyToTail(object shardingKey)
|
|
||||||
{
|
|
||||||
var shardingKeyStr = ConvertToShardingKey(shardingKey);
|
|
||||||
var m = Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % _mod);
|
|
||||||
if (m > 800)//801-999
|
|
||||||
{
|
|
||||||
return "3";
|
|
||||||
} else if (m > 600)//601-800
|
|
||||||
{
|
|
||||||
return "2";
|
|
||||||
} else if (m > 300)//301-600
|
|
||||||
{
|
|
||||||
return "1";
|
|
||||||
} else //0-300
|
|
||||||
{
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override List<string> GetAllTails()
|
|
||||||
{
|
|
||||||
return new(){"0", "1","2","3"};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
|
||||||
{
|
|
||||||
var t = ShardingKeyToTail(shardingKey);
|
|
||||||
switch (shardingOperator)
|
|
||||||
{
|
|
||||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
|
||||||
return tail => true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// public override List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
|
||||||
// {
|
|
||||||
// if (filterPhysicTables.Count > 1)
|
|
||||||
// throw new Exception($"query {nameof(SysUserRange)} not support cross table");
|
|
||||||
// return base.AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using ShardingCore.Core.VirtualRoutes;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||||
|
using ShardingCore.Test50.Domain.Entities;
|
||||||
|
|
||||||
|
namespace ShardingCore.Test50.Shardings
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Monday, 01 February 2021 15:54:55
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class SysUserSalaryVirtualRoute:AbstractShardingOperatorVirtualRoute<SysUserSalary,int>
|
||||||
|
{
|
||||||
|
protected override int ConvertToShardingKey(object shardingKey)
|
||||||
|
{
|
||||||
|
return Convert.ToInt32(shardingKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ShardingKeyToTail(object shardingKey)
|
||||||
|
{
|
||||||
|
var time = ConvertToShardingKey(shardingKey);
|
||||||
|
return TimeFormatToTail(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override List<string> GetAllTails()
|
||||||
|
{
|
||||||
|
var beginTime = new DateTime(2020, 1, 1);
|
||||||
|
var endTime = new DateTime(2021, 12, 1);
|
||||||
|
var list = new List<string>(24);
|
||||||
|
var tempTime = beginTime;
|
||||||
|
while (tempTime <= endTime)
|
||||||
|
{
|
||||||
|
list.Add($"{tempTime:yyyyMM}");
|
||||||
|
tempTime = tempTime.AddMonths(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected string TimeFormatToTail(int time)
|
||||||
|
{
|
||||||
|
var dateOfMonth=DateTime.ParseExact($"{time}","yyyyMM",System.Globalization.CultureInfo.InvariantCulture,System.Globalization.DateTimeStyles.AdjustToUniversal);
|
||||||
|
return $"{dateOfMonth:yyyyMM}";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression<Func<string, bool>> GetRouteToFilter(int shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
|
{
|
||||||
|
var t = TimeFormatToTail(shardingKey);
|
||||||
|
switch (shardingOperator)
|
||||||
|
{
|
||||||
|
case ShardingOperatorEnum.GreaterThan:
|
||||||
|
case ShardingOperatorEnum.GreaterThanOrEqual:
|
||||||
|
return tail => String.Compare(tail, t, StringComparison.Ordinal) >= 0;
|
||||||
|
case ShardingOperatorEnum.LessThan:
|
||||||
|
return tail => String.Compare(tail, t, StringComparison.Ordinal) < 0;
|
||||||
|
case ShardingOperatorEnum.LessThanOrEqual:
|
||||||
|
return tail => String.Compare(tail, t, StringComparison.Ordinal) <= 0;
|
||||||
|
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine($"shardingOperator is not equal scan all table tail");
|
||||||
|
#endif
|
||||||
|
return tail => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,7 +49,7 @@ namespace ShardingCore.Test50
|
||||||
{
|
{
|
||||||
o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
|
o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
|
||||||
o.AddSharding<SysUserModVirtualRoute>();
|
o.AddSharding<SysUserModVirtualRoute>();
|
||||||
o.AddSharding<SysUserRangeVirtualRoute>();
|
o.AddSharding<SysUserSalaryVirtualRoute>();
|
||||||
o.CreateIfNotExists((provider, config) =>
|
o.CreateIfNotExists((provider, config) =>
|
||||||
{
|
{
|
||||||
config.EnsureCreated = true;
|
config.EnsureCreated = true;
|
||||||
|
@ -78,34 +78,40 @@ namespace ShardingCore.Test50
|
||||||
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
|
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
|
||||||
if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => true))
|
if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => true))
|
||||||
{
|
{
|
||||||
var ids = Enumerable.Range(1, 100);
|
var ids = Enumerable.Range(1, 1000);
|
||||||
var userMods = new List<SysUserMod>();
|
var userMods = new List<SysUserMod>();
|
||||||
|
var userSalaries = new List<SysUserSalary>();
|
||||||
|
var beginTime = new DateTime(2020, 1, 1);
|
||||||
|
var endTime = new DateTime(2021, 12, 1);
|
||||||
foreach (var id in ids)
|
foreach (var id in ids)
|
||||||
{
|
{
|
||||||
userMods.Add(new SysUserMod()
|
userMods.Add(new SysUserMod()
|
||||||
{
|
{
|
||||||
Id = id.ToString(),
|
Id = id.ToString(),
|
||||||
Age = id,
|
Age = id,
|
||||||
Name = $"name_{id}"
|
Name = $"name_{id}",
|
||||||
|
AgeGroup=Math.Abs(id%10)
|
||||||
});
|
});
|
||||||
|
var tempTime = beginTime;
|
||||||
|
var i = 0;
|
||||||
|
while (tempTime<=endTime)
|
||||||
|
{
|
||||||
|
var dateOfMonth = $@"{tempTime:yyyyMM}";
|
||||||
|
userSalaries.Add(new SysUserSalary()
|
||||||
|
{
|
||||||
|
Id = $@"{id}{dateOfMonth}",
|
||||||
|
UserId = id.ToString(),
|
||||||
|
DateOfMonth = int.Parse(dateOfMonth),
|
||||||
|
Salary = 700000+id*100*i
|
||||||
|
});
|
||||||
|
tempTime=tempTime.AddMonths(1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await virtualDbContext.InsertRangeAsync(userMods);
|
await virtualDbContext.InsertRangeAsync(userMods);
|
||||||
|
await virtualDbContext.InsertRangeAsync(userSalaries);
|
||||||
|
|
||||||
|
|
||||||
var idRanges = Enumerable.Range(1, 1000);
|
|
||||||
var userRanges = new List<SysUserRange>();
|
|
||||||
foreach (var id in idRanges)
|
|
||||||
{
|
|
||||||
userRanges.Add(new SysUserRange()
|
|
||||||
{
|
|
||||||
Id = id.ToString(),
|
|
||||||
Age = id,
|
|
||||||
Name = $"name_range_{id}"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
await virtualDbContext.InsertRangeAsync(userRanges);
|
|
||||||
await virtualDbContext.SaveChangesAsync();
|
await virtualDbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue