更新文档添加金额表尝试针对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)`
|
||||
|
||||
#高级
|
||||
|
||||
##批量操作
|
||||
|
||||
批量操作将对应的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 :)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.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);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace ShardingCore.Test50.MySql.Domain.Entities
|
|||
/// 用户姓名
|
||||
/// </summary>
|
||||
public int Age { get; set; }
|
||||
public int AgeGroup { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
// }
|
||||
// }
|
|
@ -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.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));
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -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()
|
||||
{
|
||||
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;
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
// 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
|
||||
// {
|
||||
// if (filterPhysicTables.Count > 1)
|
||||
// throw new Exception($"query {nameof(SysUserRange)} not support cross table");
|
||||
// return base.AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
|
||||
// /*
|
||||
// * @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.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.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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace ShardingCore.Test50.Domain.Entities
|
|||
/// 用户姓名
|
||||
/// </summary>
|
||||
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
|
||||
* @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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,165 +26,218 @@ namespace ShardingCore.Test50
|
|||
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_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)
|
||||
{
|
||||
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;
|
||||
Assert.Equal(1000, moddescs.Count);
|
||||
var j = 1000;
|
||||
foreach (var age in moddescs)
|
||||
{
|
||||
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();
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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 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.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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue