更新文档添加金额表尝试针对join使用

This commit is contained in:
xuejmnet 2021-02-01 21:46:11 +08:00
parent ab43a0a117
commit 2bb8ce73a1
24 changed files with 780 additions and 399 deletions

View File

@ -223,6 +223,29 @@ AbstractSimpleShardingYearKeyLongVirtualRoute |按时间戳 |yyyy | `>,>=,<,<=,=
注:`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 :)

View File

@ -38,6 +38,8 @@ namespace ShardingCore.Core.Internal.StreamMerge.GenericMerges
}
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());
try

View File

@ -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; }
}
}

View File

@ -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>();
}
}

View File

@ -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);
}
}
}

View File

@ -2,6 +2,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using ShardingCore.Core.Internal.Visitors.GroupBys;
using ShardingCore.Extensions;
namespace ShardingCore.Core.Internal.Visitors
{
@ -16,6 +18,8 @@ namespace ShardingCore.Core.Internal.Visitors
private int? _skip;
private int? _take;
private LinkedList<PropertyOrder> _orders = new LinkedList<PropertyOrder>();
private LinkedList<string> _groups = new LinkedList<string>();
private GroupByContext _groupByContext=new GroupByContext();
public int? GetSkip()
{
@ -76,6 +80,29 @@ namespace ShardingCore.Core.Internal.Visitors
var propertyExpression=string.Join(".", properties);
_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);
}

View File

@ -23,6 +23,7 @@ namespace ShardingCore.Test50.MySql.Domain.Entities
/// 用户姓名
/// </summary>
public int Age { get; set; }
public int AgeGroup { get; set; }
}
}

View File

@ -1,27 +1,27 @@
using ShardingCore.Core;
namespace ShardingCore.Test50.MySql.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; }
}
}
// using ShardingCore.Core;
//
// namespace ShardingCore.Test50.MySql.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; }
// }
// }

View File

@ -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; }
}
}

View File

@ -1,23 +1,23 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using ShardingCore.Test50.MySql.Domain.Entities;
namespace ShardingCore.Test50.MySql.Domain.Maps
{
/*
* @Author: xjm
* @Description:
* @Date: Wednesday, 20 January 2021 10:45:47
* @Email: 326308290@qq.com
*/
public class SysUserRangeMap:IEntityTypeConfiguration<SysUserRange>
{
public void Configure(EntityTypeBuilder<SysUserRange> builder)
{
builder.HasKey(o => o.Id);
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
builder.Property(o => o.Name).HasMaxLength(128);
builder.ToTable(nameof(SysUserRange));
}
}
}
// using Microsoft.EntityFrameworkCore;
// using Microsoft.EntityFrameworkCore.Metadata.Builders;
// using ShardingCore.Test50.MySql.Domain.Entities;
//
// namespace ShardingCore.Test50.MySql.Domain.Maps
// {
// /*
// * @Author: xjm
// * @Description:
// * @Date: Wednesday, 20 January 2021 10:45:47
// * @Email: 326308290@qq.com
// */
// public class SysUserRangeMap:IEntityTypeConfiguration<SysUserRange>
// {
// public void Configure(EntityTypeBuilder<SysUserRange> builder)
// {
// builder.HasKey(o => o.Id);
// builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
// builder.Property(o => o.Name).HasMaxLength(128);
// builder.ToTable(nameof(SysUserRange));
// }
// }
// }

View File

@ -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));
}
}
}

View File

@ -26,15 +26,42 @@ namespace ShardingCore.Test50.MySql
public async Task ToList_All_Test()
{
var mods=await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
Assert.Equal(100,mods.Count);
var ranges=await _virtualDbContext.Set<SysUserRange>().ToShardingListAsync();
Assert.Equal(1000,ranges.Count);
Assert.Equal(1000,mods.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]
public async Task ToList_OrderBy_Asc_Desc_Test()
{
var modascs=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ToShardingListAsync();
Assert.Equal(100,modascs.Count);
Assert.Equal(1000,modascs.Count);
var i = 1;
foreach (var age in modascs)
{
@ -43,13 +70,12 @@ namespace ShardingCore.Test50.MySql
}
var moddescs=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ToShardingListAsync();
Assert.Equal(100,moddescs.Count);
var j = 100;
Assert.Equal(1000,moddescs.Count);
var j = 1000;
foreach (var age in moddescs)
{
Assert.Equal(j,age.Age);
j--;
}
}
[Fact]
@ -57,14 +83,11 @@ namespace ShardingCore.Test50.MySql
{
var ids = new[] {"1", "2", "3", "4"};
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)
{
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);
}
[Fact]
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();
Assert.Single(mods);
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]
public async Task ToList_Id_Not_Eq_Test()
{
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");
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]
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();
Assert.Equal(97,mods.Count);
Assert.Equal(997,mods.Count);
Assert.DoesNotContain(mods,o=>o.Id=="3");
Assert.Equal(4,mods[0].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();
Assert.Equal(86,modsDesc.Count);
Assert.Equal(986,modsDesc.Count);
Assert.DoesNotContain(mods,o=>o.Id=="3");
Assert.Equal(87,modsDesc[0].Age);
Assert.Equal(86,modsDesc[1].Age);
Assert.Equal(987,modsDesc[0].Age);
Assert.Equal(986,modsDesc[1].Age);
}
[Fact]
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();
Assert.Single(mods);
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]
public async Task ToList_Id_Eq_Not_In_Db_Test()
{
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1001").ToShardingListAsync();
Assert.Empty(mods);
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1001").ToShardingListAsync();
Assert.Empty(ranges);
}
[Fact]
public async Task ToList_Name_Eq_Not_In_Db_Test()
{
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_1001").ToShardingListAsync();
Assert.Empty(mods);
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ToShardingListAsync();
Assert.Empty(ranges);
}
[Fact]
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();
Assert.True(sysUserModAge!=null&&sysUserModAge.Id=="1");
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();
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
var sysUserModDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModDesc!=null&&sysUserModDesc.Id=="99");
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
Assert.True(sysUserModDesc!=null&&sysUserModDesc.Id=="999");
}
[Fact]
public async Task FirstOrDefault2()
{
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
Assert.NotNull(sysUserMod);
Assert.True(sysUserMod.Id=="1");
}
[Fact]
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();
Assert.NotNull(sysUserMod);
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]
public async Task FirstOrDefault4()
@ -166,25 +170,98 @@ namespace ShardingCore.Test50.MySql
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
Assert.NotNull(sysUserMod);
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]
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);
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ShardingFirstOrDefaultAsync();
Assert.Null(sysUserRange);
}
[Fact]
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);
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_100").ShardingCountAsync();
Assert.Equal(99,b);
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_1000").ShardingCountAsync();
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;
// }
}
}

View File

@ -1,70 +1,70 @@
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.MySql.Domain.Entities;
namespace ShardingCore.Test50.MySql.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);
// }
}
}
// 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.MySql.Domain.Entities;
//
// namespace ShardingCore.Test50.MySql.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);
// // }
// }
// }

View File

@ -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;
}
}
}
}
}

View File

@ -44,7 +44,7 @@ namespace ShardingCore.Test50.MySql
o.ConnectionString = hostBuilderContext.Configuration.GetSection("MySql")["ConnectionString"];
o.ServerVersion = new MySqlServerVersion(new Version());
o.AddSharding<SysUserModVirtualRoute>();
o.AddSharding<SysUserRangeVirtualRoute>();
o.AddSharding<SysUserSalaryVirtualRoute>();
o.CreateIfNotExists((provider, config) =>
{
config.EnsureCreated = true;
@ -73,34 +73,41 @@ namespace ShardingCore.Test50.MySql
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
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 userSalaries = new List<SysUserSalary>();
var beginTime = new DateTime(2020, 1, 1);
var endTime = new DateTime(2021, 12, 1);
foreach (var id in ids)
{
userMods.Add(new SysUserMod()
{
Id = id.ToString(),
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(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();
}
}

View File

@ -23,6 +23,7 @@ namespace ShardingCore.Test50.Domain.Entities
/// 用户姓名
/// </summary>
public int Age { get; set; }
public int AgeGroup { get; set; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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
{
}
}

View File

@ -7,17 +7,17 @@ namespace ShardingCore.Test50.Domain.Maps
/*
* @Author: xjm
* @Description:
* @Date: Wednesday, 20 January 2021 10:45:47
* @Date: Monday, 01 February 2021 15:42:35
* @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.Property(o => o.Id).IsRequired().HasMaxLength(128);
builder.Property(o => o.Name).HasMaxLength(128);
builder.ToTable(nameof(SysUserRange));
builder.Property(o => o.UserId).IsRequired().HasMaxLength(128);
builder.ToTable(nameof(SysUserSalary));
}
}
}

View File

@ -25,166 +25,219 @@ namespace ShardingCore.Test50
[Fact]
public async Task ToList_All_Test()
{
var mods=await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
Assert.Equal(100,mods.Count);
var ranges=await _virtualDbContext.Set<SysUserRange>().ToShardingListAsync();
Assert.Equal(1000,ranges.Count);
var mods = await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
Assert.Equal(1000, mods.Count);
}
[Fact]
public async Task ToList_OrderBy_Asc_Desc_Test()
{
var modascs=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ToShardingListAsync();
Assert.Equal(100,modascs.Count);
var modascs = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToShardingListAsync();
Assert.Equal(1000, modascs.Count);
var i = 1;
foreach (var age in modascs)
{
Assert.Equal(i,age.Age);
Assert.Equal(i, age.Age);
i++;
}
var moddescs=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ToShardingListAsync();
Assert.Equal(100,moddescs.Count);
var j = 100;
var moddescs = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToShardingListAsync();
Assert.Equal(1000, moddescs.Count);
var j = 1000;
foreach (var age in moddescs)
{
Assert.Equal(j,age.Age);
Assert.Equal(j, age.Age);
j--;
}
}
}
}
[Fact]
public async Task ToList_Id_In_Test()
{
var ids = new[] {"1", "2", "3", "4"};
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();
var sysUserMods = await _virtualDbContext.Set<SysUserMod>().Where(o => ids.Contains(o.Id)).ToShardingListAsync();
foreach (var id in ids)
{
Assert.Contains(sysUserMods, o =>o.Id==id);
Assert.Contains(sysUserRanges, o =>o.Id==id);
Assert.Contains(sysUserMods, 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]
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.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);
Assert.Equal("3", mods[0].Id);
}
[Fact]
public async Task ToList_Id_Not_Eq_Test()
{
var mods=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id!="3").ToShardingListAsync();
Assert.Equal(99,mods.Count);
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");
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").ToShardingListAsync();
Assert.Equal(999, mods.Count);
Assert.DoesNotContain(mods, o => o.Id == "3");
}
[Fact]
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();
Assert.Equal(97,mods.Count);
Assert.DoesNotContain(mods,o=>o.Id=="3");
Assert.Equal(4,mods[0].Age);
Assert.Equal(5,mods[1].Age);
var mods = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").OrderBy(o => o.Age).Skip(2).ToShardingListAsync();
Assert.Equal(997, mods.Count);
Assert.DoesNotContain(mods, o => o.Id == "3");
Assert.Equal(4, mods[0].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();
Assert.Equal(86,modsDesc.Count);
Assert.DoesNotContain(mods,o=>o.Id=="3");
Assert.Equal(87,modsDesc[0].Age);
Assert.Equal(86,modsDesc[1].Age);
var modsDesc = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id != "3").OrderByDescending(o => o.Age).Skip(13).ToShardingListAsync();
Assert.Equal(986, modsDesc.Count);
Assert.DoesNotContain(mods, o => o.Id == "3");
Assert.Equal(987, modsDesc[0].Age);
Assert.Equal(986, modsDesc[1].Age);
}
[Fact]
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.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);
Assert.Equal("3", mods[0].Id);
}
[Fact]
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);
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1001").ToShardingListAsync();
Assert.Empty(ranges);
}
[Fact]
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);
var ranges=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ToShardingListAsync();
Assert.Empty(ranges);
}
[Fact]
public async Task FirstOrDefault_Order_By_Id_Test()
{
var sysUserModAge=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Age).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModAge!=null&&sysUserModAge.Id=="1");
var sysUserModAgeDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Age).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModAgeDesc!=null&&sysUserModAgeDesc.Id=="100");
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
var sysUserModAge = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModAge != null && sysUserModAge.Id == "1");
var sysUserModAgeDesc = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModAgeDesc != null && sysUserModAgeDesc.Id == "1000");
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserMod != null && sysUserMod.Id == "1");
var sysUserModDesc=await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o=>o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModDesc!=null&&sysUserModDesc.Id=="99");
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().OrderBy(o=>o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
var sysUserModDesc = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Id).ShardingFirstOrDefaultAsync();
Assert.True(sysUserModDesc != null && sysUserModDesc.Id == "999");
}
[Fact]
public async Task FirstOrDefault2()
{
var sysUserMod=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
Assert.True(sysUserMod!=null&&sysUserMod.Id=="1");
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id=="1").ShardingFirstOrDefaultAsync();
Assert.True(sysUserRange!=null&&sysUserRange.Id=="1");
var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "1").ShardingFirstOrDefaultAsync();
Assert.NotNull(sysUserMod);
Assert.True(sysUserMod.Id == "1");
}
[Fact]
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.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);
Assert.Equal("2", sysUserMod.Id);
}
[Fact]
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.True(sysUserMod.Id!="1");
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Id!="1").ShardingFirstOrDefaultAsync();
Assert.NotNull(sysUserRange);
Assert.True(sysUserRange.Id!="1");
Assert.True(sysUserMod.Id != "1");
}
[Fact]
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);
var sysUserRange=await _virtualDbContext.Set<SysUserRange>().Where(o=>o.Name=="name_range_1001").ShardingFirstOrDefaultAsync();
Assert.Null(sysUserRange);
}
[Fact]
public async Task Count_Test()
{
var a=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name=="name_100").ShardingCountAsync();
Assert.Equal(1,a);
var b=await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Name!="name_100").ShardingCountAsync();
Assert.Equal(99,b);
var a = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1000").ShardingCountAsync();
Assert.Equal(1, a);
var b = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name != "name_1000").ShardingCountAsync();
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;
// }
}
}

View File

@ -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);
// }
}
}

View File

@ -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;
}
}
}
}
}

View File

@ -49,7 +49,7 @@ namespace ShardingCore.Test50
{
o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
o.AddSharding<SysUserModVirtualRoute>();
o.AddSharding<SysUserRangeVirtualRoute>();
o.AddSharding<SysUserSalaryVirtualRoute>();
o.CreateIfNotExists((provider, config) =>
{
config.EnsureCreated = true;
@ -78,34 +78,40 @@ namespace ShardingCore.Test50
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
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 userSalaries = new List<SysUserSalary>();
var beginTime = new DateTime(2020, 1, 1);
var endTime = new DateTime(2021, 12, 1);
foreach (var id in ids)
{
userMods.Add(new SysUserMod()
{
Id = id.ToString(),
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(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();
}
}