修复优化bug
This commit is contained in:
parent
73008f2ac8
commit
7aa0418763
README.mdShardingCore.slnnuget-publish.batDIExtension.cs
samples
Sample.MySql
Sample.SqlServer
Sample.SqlServer3x
Samples.AutoByDate.SqlServer
src/ShardingCore
Core
PhysicTables
ShardingAccessors
ShardingConstant.csVirtualRoutes/TableRoutes/RoutingRuleEngine
DbContexts
EFCores
IShardingDbContextOptionsBuilderConfig.csSharding
AbstractShardingDbContext.cs
ShardingConfigOption.csAbstractions
ShardingDbContextOptionsBuilderConfig.csStreamMergeContext.csStreamMergeContextFactory.csStreamMergeEngines
test
ShardingCore.Test50.MySql
ShardingCore.Test50
ShardingCoreTestBatch
ShardingCoreTestSqlServer3x
101
README.md
101
README.md
|
@ -190,28 +190,18 @@ Oracle | 支持 | 未测试
|
||||||
//services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx3;Integrated Security=True"));
|
//services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx3;Integrated Security=True"));
|
||||||
|
|
||||||
//添加shardingdbcontext support life scope
|
//添加shardingdbcontext support life scope
|
||||||
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;MultipleActiveResultSets=True;")
|
|
||||||
,op =>
|
|
||||||
{
|
|
||||||
op.EnsureCreatedWithOutShardingTable = true;
|
|
||||||
op.CreateShardingTableOnStart = true;
|
|
||||||
op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger));
|
|
||||||
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;")
|
||||||
// //不支持MARS不支持追踪的
|
,op =>
|
||||||
// services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;")
|
{
|
||||||
// ,op =>
|
op.EnsureCreatedWithOutShardingTable = true;
|
||||||
// {
|
op.CreateShardingTableOnStart = true;
|
||||||
// op.EnsureCreatedWithOutShardingTable = true;
|
//不支持mars额外加一条字符串的
|
||||||
// op.CreateShardingTableOnStart = true;
|
op.UseShardingOptionsBuilder(
|
||||||
// //不支持mars额外加一条字符串的
|
(connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),
|
||||||
// op.UseShardingOptionsBuilder(
|
builder => builder.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;").UseLoggerFactory(efLogger));
|
||||||
// (connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),
|
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||||
// (connString, builder) => builder.UseSqlServer(connString).UseLoggerFactory(efLogger));
|
});
|
||||||
// op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -235,37 +225,25 @@ Oracle | 支持 | 未测试
|
||||||
|
|
||||||
public async Task ToList_All()
|
public async Task ToList_All()
|
||||||
{
|
{
|
||||||
//查询list集合
|
|
||||||
var all=await _defaultShardingDbContext.Set<SysUserMod>().ToListAsync();
|
var mods = await _virtualDbContext.Set<SysUserMod>().ToListAsync();
|
||||||
//链接查询
|
Assert.Equal(1000, mods.Count);
|
||||||
var list = await (from u in _defaultShardingDbContext.Set<SysUserMod>()
|
|
||||||
join salary in _defaultShardingDbContext.Set<SysUserSalary>()
|
var modOrders1 = await _virtualDbContext.Set<SysUserMod>().OrderBy(o => o.Age).ToListAsync();
|
||||||
on u.Id equals salary.UserId
|
int ascAge = 1;
|
||||||
select new
|
foreach (var sysUserMod in modOrders1)
|
||||||
{
|
{
|
||||||
Salary = salary.Salary,
|
Assert.Equal(ascAge, sysUserMod.Age);
|
||||||
DateOfMonth = salary.DateOfMonth,
|
ascAge++;
|
||||||
Name = u.Name
|
}
|
||||||
}).ToListAsync();
|
|
||||||
//聚合查询
|
var modOrders2 = await _virtualDbContext.Set<SysUserMod>().OrderByDescending(o => o.Age).ToListAsync();
|
||||||
var ids = new[] {"200", "300"};
|
int descAge = 1000;
|
||||||
var dateOfMonths = new[] {202111, 202110};
|
foreach (var sysUserMod in modOrders2)
|
||||||
var group = await (from u in _defaultShardingDbContext.Set<SysUserSalary>()
|
{
|
||||||
.Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth))
|
Assert.Equal(descAge, sysUserMod.Age);
|
||||||
group u by new
|
descAge--;
|
||||||
{
|
}
|
||||||
UId = u.UserId
|
|
||||||
}
|
|
||||||
into g
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
GroupUserId = g.Key.UId,
|
|
||||||
Count = g.Count(),
|
|
||||||
TotalSalary = g.Sum(o => o.Salary),
|
|
||||||
AvgSalary = g.Average(o => o.Salary),
|
|
||||||
MinSalary = g.Min(o => o.Salary),
|
|
||||||
MaxSalary = g.Max(o => o.Salary)
|
|
||||||
}).ToListAsync();
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
更多操作可以参考单元测试
|
更多操作可以参考单元测试
|
||||||
|
@ -342,27 +320,12 @@ AbstractSimpleShardingYearKeyLongVirtualTableRoute |按时间戳 |yyyy | `>,>=,<
|
||||||
- startup是否已经添加虚拟路由
|
- startup是否已经添加虚拟路由
|
||||||
- startup是否已经添加bootstrapper.start()
|
- startup是否已经添加bootstrapper.start()
|
||||||
|
|
||||||
```c#
|
```c#添加追踪
|
||||||
// //不支持MARS不支持追踪的
|
|
||||||
// services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;")
|
|
||||||
// ,op =>
|
|
||||||
// {
|
|
||||||
// op.EnsureCreatedWithOutShardingTable = true;
|
|
||||||
// op.CreateShardingTableOnStart = true;
|
|
||||||
// //不支持mars额外加一条字符串的
|
|
||||||
// op.UseShardingOptionsBuilder(
|
|
||||||
// (connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),
|
|
||||||
// (connString, builder) => builder.UseSqlServer(connString).UseLoggerFactory(efLogger));
|
|
||||||
// op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
|
||||||
// });
|
|
||||||
```
|
|
||||||
如果数据库不支持mars但是我又要支持追踪该怎么办
|
|
||||||
```c#
|
|
||||||
|
|
||||||
var sresult = _defaultTableDbContext.Set<SysUserMod>().ToList();
|
var sresult = _defaultTableDbContext.Set<SysUserMod>().ToList();
|
||||||
|
|
||||||
var sysUserMod98 = result.FirstOrDefault(o => o.Id == "98");
|
var sysUserMod98 = result.FirstOrDefault(o => o.Id == "98");
|
||||||
_defaultTableDbContext.Attach(sysUserMod98);
|
_defaultTableDbContext.Attach(sysUserMod98);//添加追踪
|
||||||
sysUserMod98.Name = "name_update"+new Random().Next(1,99)+"_98";
|
sysUserMod98.Name = "name_update"+new Random().Next(1,99)+"_98";
|
||||||
await _defaultTableDbContext.SaveChangesAsync();
|
await _defaultTableDbContext.SaveChangesAsync();
|
||||||
--log info
|
--log info
|
||||||
|
|
|
@ -31,10 +31,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.MySql", "samples\Sam
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.SqlServer3x", "samples\Sample.SqlServer3x\Sample.SqlServer3x.csproj", "{447D5357-F095-45DE-9DA5-2D9997237366}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.SqlServer3x", "samples\Sample.SqlServer3x\Sample.SqlServer3x.csproj", "{447D5357-F095-45DE-9DA5-2D9997237366}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCoreTestSqlServer3x", "test\ShardingCoreTestSqlServer3x\ShardingCoreTestSqlServer3x.csproj", "{1CE858B8-56D8-4009-BF46-EE0F79F259D1}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardingCoreTestBatch", "test\ShardingCoreTestBatch\ShardingCoreTestBatch.csproj", "{54BA9F11-96CD-47DF-97FB-0BC83D2F7081}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -77,14 +73,6 @@ Global
|
||||||
{447D5357-F095-45DE-9DA5-2D9997237366}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{447D5357-F095-45DE-9DA5-2D9997237366}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{447D5357-F095-45DE-9DA5-2D9997237366}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{447D5357-F095-45DE-9DA5-2D9997237366}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{447D5357-F095-45DE-9DA5-2D9997237366}.Release|Any CPU.Build.0 = Release|Any CPU
|
{447D5357-F095-45DE-9DA5-2D9997237366}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{1CE858B8-56D8-4009-BF46-EE0F79F259D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{1CE858B8-56D8-4009-BF46-EE0F79F259D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{1CE858B8-56D8-4009-BF46-EE0F79F259D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{1CE858B8-56D8-4009-BF46-EE0F79F259D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{54BA9F11-96CD-47DF-97FB-0BC83D2F7081}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{54BA9F11-96CD-47DF-97FB-0BC83D2F7081}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{54BA9F11-96CD-47DF-97FB-0BC83D2F7081}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{54BA9F11-96CD-47DF-97FB-0BC83D2F7081}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -99,8 +87,6 @@ Global
|
||||||
{C34FCF48-1A98-4268-BFEE-6C9BFC7FD539} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
{C34FCF48-1A98-4268-BFEE-6C9BFC7FD539} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||||
{90675788-D5C3-415A-9C18-FF159A75B4D5} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
{90675788-D5C3-415A-9C18-FF159A75B4D5} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||||
{447D5357-F095-45DE-9DA5-2D9997237366} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
{447D5357-F095-45DE-9DA5-2D9997237366} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||||
{1CE858B8-56D8-4009-BF46-EE0F79F259D1} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
|
||||||
{54BA9F11-96CD-47DF-97FB-0BC83D2F7081} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291}
|
SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
:start
|
:start
|
||||||
::定义版本
|
::定义版本
|
||||||
set EFCORE2=2.2.0.05-pre
|
set EFCORE2=2.2.0.06-pre
|
||||||
set EFCORE3=3.2.0.05-pre
|
set EFCORE3=3.2.0.06-pre
|
||||||
set EFCORE5=5.2.0.05-pre
|
set EFCORE5=5.2.0.06-pre
|
||||||
|
|
||||||
::删除所有bin与obj下的文件
|
::删除所有bin与obj下的文件
|
||||||
@echo off
|
@echo off
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src2x\ShardingCore.MySql.2x\ShardingCore.MySql.2x.csproj" />
|
<ProjectReference Include="..\..\src3x\ShardingCore.3x\ShardingCore.3x.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,12 @@ namespace Sample.SqlServer
|
||||||
|
|
||||||
|
|
||||||
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(
|
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(
|
||||||
o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;MultipleActiveResultSets=True;")
|
o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;")
|
||||||
, op =>
|
, op =>
|
||||||
{
|
{
|
||||||
op.EnsureCreatedWithOutShardingTable = true;
|
op.EnsureCreatedWithOutShardingTable = true;
|
||||||
op.CreateShardingTableOnStart = true;
|
op.CreateShardingTableOnStart = true;
|
||||||
op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger));
|
op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger), builder => builder.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;").UseLoggerFactory(efLogger));
|
||||||
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||||
});
|
});
|
||||||
////不支持MARS不支持追踪的
|
////不支持MARS不支持追踪的
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src3x\ShardingCore.SqlServer.3x\ShardingCore.SqlServer.3x.csproj" />
|
<ProjectReference Include="..\..\src3x\ShardingCore.3x\ShardingCore.3x.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\ShardingCore.SqlServer\ShardingCore.SqlServer.csproj" />
|
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace ShardingCore.Core.PhysicTables
|
||||||
public string OriginalName { get; }
|
public string OriginalName { get; }
|
||||||
public string TailPrefix =>VirtualTable.ShardingConfig.TailPrefix;
|
public string TailPrefix =>VirtualTable.ShardingConfig.TailPrefix;
|
||||||
public string Tail { get; }
|
public string Tail { get; }
|
||||||
public Type VirtualType => VirtualTable.EntityType;
|
public Type EntityType => VirtualTable.EntityType;
|
||||||
public IVirtualTable VirtualTable { get; }
|
public IVirtualTable VirtualTable { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,7 +30,7 @@ namespace ShardingCore.Core.PhysicTables
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 映射类类型
|
/// 映射类类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Type VirtualType { get; }
|
Type EntityType { get; }
|
||||||
IVirtualTable VirtualTable { get; }
|
IVirtualTable VirtualTable { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace ShardingCore.Core.ShardingAccessors.Abstractions
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Tuesday, 22 December 2020 15:13:44
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public interface IShardingAccessor
|
||||||
|
{
|
||||||
|
ShardingContext ShardingContext { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
namespace ShardingCore.Core.ShardingAccessors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Wednesday, 23 December 2020 07:51:00
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// 查询scope创建
|
||||||
|
/// </summary>
|
||||||
|
public interface IShardingScopeFactory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 创建查询scope
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
ShardingScope CreateScope();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System.Threading;
|
||||||
|
using ShardingCore.Core.ShardingAccessors.Abstractions;
|
||||||
|
using ShardingCore.Core.VirtualTables;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.ShardingAccessors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Tuesday, 22 December 2020 15:14:15
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// 分表访问器
|
||||||
|
/// </summary>
|
||||||
|
public class ShardingAccessor : IShardingAccessor
|
||||||
|
{
|
||||||
|
private static AsyncLocal<ShardingContext> _shardingContext = new AsyncLocal<ShardingContext>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分表访问器
|
||||||
|
/// </summary>
|
||||||
|
public ShardingAccessor(IVirtualTableManager virtualTableManager)
|
||||||
|
{
|
||||||
|
VirtualTableManager = virtualTableManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ShardingContext ShardingContext
|
||||||
|
{
|
||||||
|
get => _shardingContext.Value;
|
||||||
|
set => _shardingContext.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 虚拟表管理者
|
||||||
|
/// </summary>
|
||||||
|
public IVirtualTableManager VirtualTableManager { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
|
using ShardingCore.Core.VirtualTables;
|
||||||
|
using ShardingCore.Extensions;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.ShardingAccessors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Tuesday, 22 December 2020 15:04:47
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class ShardingContext
|
||||||
|
{
|
||||||
|
private ShardingContext(RouteResult routeResult)
|
||||||
|
{
|
||||||
|
foreach (var physicTable in routeResult.ReplaceTables)
|
||||||
|
{
|
||||||
|
_shardingTables.Add(physicTable.EntityType, physicTable.Tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分表操作上下文 key:物理表名 value:虚拟表和本次分表tails
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<Type, string> _shardingTables = new Dictionary<Type, string>();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建一个分表上下文
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ShardingContext Create(RouteResult routeResult)
|
||||||
|
{
|
||||||
|
return new ShardingContext(routeResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取分表信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entityType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string GetContextQueryTail(Type entityType)
|
||||||
|
{
|
||||||
|
if (_shardingTables.ContainsKey(entityType))
|
||||||
|
return _shardingTables[entityType];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否是空的
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsEmpty()
|
||||||
|
{
|
||||||
|
return _shardingTables.IsEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using ShardingCore.Core.ShardingAccessors.Abstractions;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.ShardingAccessors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Wednesday, 23 December 2020 07:51:30
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class ShardingScope : IDisposable
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分表配置访问器
|
||||||
|
/// </summary>
|
||||||
|
public IShardingAccessor ShardingAccessor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shardingAccessor"></param>
|
||||||
|
public ShardingScope(IShardingAccessor shardingAccessor)
|
||||||
|
{
|
||||||
|
ShardingAccessor = shardingAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 回收
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ShardingAccessor.ShardingContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
using ShardingCore.Core.ShardingAccessors.Abstractions;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core.ShardingAccessors
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: Wednesday, 23 December 2020 08:11:06
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// 分表查询环境创建
|
||||||
|
/// </summary>
|
||||||
|
public class ShardingScopeFactory : IShardingScopeFactory
|
||||||
|
{
|
||||||
|
private readonly IShardingAccessor _shardingAccessor;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="shardingAccessor"></param>
|
||||||
|
public ShardingScopeFactory(IShardingAccessor shardingAccessor)
|
||||||
|
{
|
||||||
|
_shardingAccessor = shardingAccessor;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 创建scope
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public ShardingScope CreateScope()
|
||||||
|
{
|
||||||
|
return new ShardingScope(_shardingAccessor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace ShardingCore.Core
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @Author: xjm
|
||||||
|
* @Description:
|
||||||
|
* @Date: 2021/8/21 13:04:38
|
||||||
|
* @Ver: 1.0
|
||||||
|
* @Email: 326308290@qq.com
|
||||||
|
*/
|
||||||
|
public class ShardingConstant
|
||||||
|
{
|
||||||
|
public const string EMPTY_SHARDING_TAIL_ID = "EMPTY_SHARDING_TAIL_ID";
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core.PhysicTables;
|
using ShardingCore.Core.PhysicTables;
|
||||||
using ShardingCore.Core.VirtualTables;
|
using ShardingCore.Core.VirtualTables;
|
||||||
|
using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
|
@ -90,6 +91,8 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool EnableMultiEntityQuery = false;
|
||||||
|
|
||||||
public IEnumerable<RouteResult> Route<T>(Type shardingDbContextType, RouteRuleContext<T> routeRuleContext)
|
public IEnumerable<RouteResult> Route<T>(Type shardingDbContextType, RouteRuleContext<T> routeRuleContext)
|
||||||
{
|
{
|
||||||
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
|
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
|
||||||
|
@ -97,6 +100,10 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
|
|
||||||
|
|
||||||
var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
|
var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
|
||||||
|
if (shardingEntities.Count() > 1&& !EnableMultiEntityQuery)
|
||||||
|
{
|
||||||
|
throw new ShardingCoreException("not support multi entity query");
|
||||||
|
}
|
||||||
foreach (var shardingEntity in shardingEntities)
|
foreach (var shardingEntity in shardingEntities)
|
||||||
{
|
{
|
||||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntity);
|
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntity);
|
||||||
|
|
|
@ -12,6 +12,8 @@ using ShardingCore.Sharding;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
using ShardingCore.TableCreator;
|
using ShardingCore.TableCreator;
|
||||||
using System;
|
using System;
|
||||||
|
using ShardingCore.Core.ShardingAccessors;
|
||||||
|
using ShardingCore.Core.ShardingAccessors.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore
|
namespace ShardingCore
|
||||||
{
|
{
|
||||||
|
@ -43,7 +45,7 @@ namespace ShardingCore
|
||||||
|
|
||||||
|
|
||||||
//添加创建TActualDbContext 的 创建者
|
//添加创建TActualDbContext 的 创建者
|
||||||
var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(shardingConfigOptions.SameConnectionConfigure,shardingConfigOptions.NotSupportMARSConfigure);
|
var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(shardingConfigOptions.SameConnectionConfigure,shardingConfigOptions.DefaultQueryConfigure);
|
||||||
services.AddSingleton<IShardingDbContextOptionsBuilderConfig, ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp=> config);
|
services.AddSingleton<IShardingDbContextOptionsBuilderConfig, ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp=> config);
|
||||||
|
|
||||||
//添加创建TActualDbContext创建者
|
//添加创建TActualDbContext创建者
|
||||||
|
@ -77,8 +79,8 @@ namespace ShardingCore
|
||||||
//分表引擎
|
//分表引擎
|
||||||
services.AddSingleton<IRouteRuleEngine, QueryRouteRuleEngines>();
|
services.AddSingleton<IRouteRuleEngine, QueryRouteRuleEngines>();
|
||||||
//services.AddSingleton(typeof(IVirtualTable<>), typeof(OneDbVirtualTable<>));
|
//services.AddSingleton(typeof(IVirtualTable<>), typeof(OneDbVirtualTable<>));
|
||||||
//services.AddSingleton<IShardingAccessor, ShardingAccessor>();
|
services.AddSingleton<IShardingAccessor, ShardingAccessor>();
|
||||||
//services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
|
services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace ShardingCore.DbContexts
|
||||||
}
|
}
|
||||||
var tail=shardingDbContextOptions.Tail;
|
var tail=shardingDbContextOptions.Tail;
|
||||||
|
|
||||||
var dbContext = shardingDbContextCreatorConfig.Creator(shardingDbContextOptions);
|
var dbContext = shardingDbContextCreatorConfig.Creator(shardingDbContextOptions);
|
||||||
if (!string.IsNullOrWhiteSpace(tail) && dbContext is IShardingTableDbContext shardingTableDbContext)
|
if (!string.IsNullOrWhiteSpace(tail) && dbContext is IShardingTableDbContext shardingTableDbContext)
|
||||||
{
|
{
|
||||||
shardingTableDbContext.SetShardingTableDbContextTail(tail);
|
shardingTableDbContext.SetShardingTableDbContextTail(tail);
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Text;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using ShardingCore.Core.ShardingAccessors.Abstractions;
|
||||||
using ShardingCore.Core.VirtualTables;
|
using ShardingCore.Core.VirtualTables;
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
|
@ -33,6 +34,8 @@ namespace ShardingCore.EFCores
|
||||||
if (context is IShardingTableDbContext shardingTableDbContext)
|
if (context is IShardingTableDbContext shardingTableDbContext)
|
||||||
{
|
{
|
||||||
var tail = shardingTableDbContext.GetShardingTableDbContextTail();
|
var tail = shardingTableDbContext.GetShardingTableDbContextTail();
|
||||||
|
//if (tail.StartsWith("EMPTY_SHARDING_TAIL_ID"))
|
||||||
|
// tail = null;
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(tail))
|
if (!string.IsNullOrWhiteSpace(tail))
|
||||||
{
|
{
|
||||||
|
@ -43,20 +46,41 @@ namespace ShardingCore.EFCores
|
||||||
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => o.ClrType.IsShardingTable() && typeMap.Contains(o.ClrType));
|
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => o.ClrType.IsShardingTable() && typeMap.Contains(o.ClrType));
|
||||||
foreach (var entityType in mutableEntityTypes)
|
foreach (var entityType in mutableEntityTypes)
|
||||||
{
|
{
|
||||||
var shardingEntityConfig = ShardingKeyUtil.Parse(entityType.ClrType);
|
MappingToTable(entityType.ClrType, modelBuilder, tail);
|
||||||
var shardingEntity = shardingEntityConfig.ShardingEntityType;
|
|
||||||
var tailPrefix = shardingEntityConfig.TailPrefix;
|
|
||||||
var entity = modelBuilder.Entity(shardingEntity);
|
|
||||||
var tableName = shardingEntityConfig.ShardingOriginalTable;
|
|
||||||
if (string.IsNullOrWhiteSpace(tableName))
|
|
||||||
throw new ArgumentNullException($"{shardingEntity}: not found original table name。");
|
|
||||||
#if DEBUG
|
|
||||||
Console.WriteLine($"mapping table :[tableName]-->[{tableName}{tailPrefix}{tail}]");
|
|
||||||
#endif
|
|
||||||
entity.ToTable($"{tableName}{tailPrefix}{tail}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
|
||||||
|
// var shardingAccessor = ShardingContainer.Services.GetService<IShardingAccessor>();
|
||||||
|
// if (shardingAccessor?.ShardingContext != null)
|
||||||
|
// {
|
||||||
|
// var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => o.ClrType.IsShardingTable()).ToArray();
|
||||||
|
// foreach (var entityType in mutableEntityTypes)
|
||||||
|
// {
|
||||||
|
// var queryTail = shardingAccessor.ShardingContext.GetContextQueryTail(entityType.ClrType);
|
||||||
|
// if (queryTail != null)
|
||||||
|
// {
|
||||||
|
// MappingToTable(entityType.ClrType,modelBuilder, queryTail);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void MappingToTable(Type clrType,ModelBuilder modelBuilder,string tail)
|
||||||
|
{
|
||||||
|
var shardingEntityConfig = ShardingKeyUtil.Parse(clrType);
|
||||||
|
var shardingEntity = shardingEntityConfig.ShardingEntityType;
|
||||||
|
var tailPrefix = shardingEntityConfig.TailPrefix;
|
||||||
|
var entity = modelBuilder.Entity(shardingEntity);
|
||||||
|
var tableName = shardingEntityConfig.ShardingOriginalTable;
|
||||||
|
if (string.IsNullOrWhiteSpace(tableName))
|
||||||
|
throw new ArgumentNullException($"{shardingEntity}: not found original table name。");
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine($"mapping table :[tableName]-->[{tableName}{tailPrefix}{tail}]");
|
||||||
|
#endif
|
||||||
|
entity.ToTable($"{tableName}{tailPrefix}{tail}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@ namespace ShardingCore
|
||||||
public interface IShardingDbContextOptionsBuilderConfig
|
public interface IShardingDbContextOptionsBuilderConfig
|
||||||
{
|
{
|
||||||
Type ShardingDbContextType { get; }
|
Type ShardingDbContextType { get; }
|
||||||
bool SupportMARS { get; }
|
|
||||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder);
|
DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString, DbContextOptionsBuilder dbContextOptionsBuilder);
|
DbContextOptionsBuilder UseDbContextOptionsBuilder(DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace ShardingCore.Sharding
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public abstract class AbstractShardingDbContext<T> : DbContext, IShardingTableDbContext<T> where T : DbContext, IShardingTableDbContext
|
public abstract class AbstractShardingDbContext<T> : DbContext, IShardingTableDbContext<T> where T : DbContext, IShardingTableDbContext
|
||||||
{
|
{
|
||||||
private readonly string EMPTY_SHARDING_TAIL_ID = Guid.NewGuid().ToString("n");
|
private readonly string EMPTY_SHARDING_TAIL_ID = ShardingConstant.EMPTY_SHARDING_TAIL_ID+ Guid.NewGuid().ToString("n");
|
||||||
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
||||||
private readonly IVirtualTableManager _virtualTableManager;
|
private readonly IVirtualTableManager _virtualTableManager;
|
||||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||||
|
@ -62,22 +62,21 @@ namespace ShardingCore.Sharding
|
||||||
return (DbContextOptionsBuilder<T>) Activator.CreateInstance(type);
|
return (DbContextOptionsBuilder<T>) Activator.CreateInstance(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbContextOptions<T> GetDbContextOptions()
|
private DbContextOptions<T> CreateShareDbContextOptions()
|
||||||
{
|
{
|
||||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||||
var dbConnection = Database.GetDbConnection();
|
var dbConnection = Database.GetDbConnection();
|
||||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
||||||
return dbContextOptionBuilder.Options;
|
return dbContextOptionBuilder.Options;
|
||||||
}
|
}
|
||||||
private DbContextOptions<T> GetParallelDbContextOptions()
|
private DbContextOptions<T> CreateMonopolyDbContextOptions()
|
||||||
{
|
{
|
||||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||||
var connectionString = Database.GetDbConnection().ConnectionString;
|
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbContextOptionBuilder);
|
||||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(connectionString, dbContextOptionBuilder);
|
|
||||||
return dbContextOptionBuilder.Options;
|
return dbContextOptionBuilder.Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ShardingDbContextOptions CreateSameShardingDbContextOptions(string tail)
|
private ShardingDbContextOptions GetShareShardingDbContextOptions(string tail)
|
||||||
{
|
{
|
||||||
if (_dbContextOptions == null)
|
if (_dbContextOptions == null)
|
||||||
{
|
{
|
||||||
|
@ -85,26 +84,26 @@ namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
if (_dbContextOptions == null)
|
if (_dbContextOptions == null)
|
||||||
{
|
{
|
||||||
_dbContextOptions = GetDbContextOptions();
|
_dbContextOptions = CreateShareDbContextOptions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ShardingDbContextOptions(_dbContextOptions, tail);
|
return new ShardingDbContextOptions(_dbContextOptions, tail);
|
||||||
}
|
}
|
||||||
private ShardingDbContextOptions CreateParallelShardingDbContextOptions(string tail)
|
private ShardingDbContextOptions CetMonopolyShardingDbContextOptions(string tail)
|
||||||
{
|
{
|
||||||
return new ShardingDbContextOptions(GetParallelDbContextOptions(), tail);
|
return new ShardingDbContextOptions(CreateMonopolyDbContextOptions(), tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DbContext GetDbContext(bool track, string tail)
|
public DbContext GetDbContext(bool track, string tail)
|
||||||
{
|
{
|
||||||
if (SupportMARS() || track)
|
if (track)
|
||||||
{
|
{
|
||||||
if (!_dbContextCaches.TryGetValue(tail, out var dbContext))
|
if (!_dbContextCaches.TryGetValue(tail, out var dbContext))
|
||||||
{
|
{
|
||||||
dbContext = _shardingDbContextFactory.Create(ShardingDbContextType, CreateSameShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
dbContext = _shardingDbContextFactory.Create(ShardingDbContextType, GetShareShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
||||||
_dbContextCaches.TryAdd(tail, dbContext);
|
_dbContextCaches.TryAdd(tail, dbContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +111,7 @@ namespace ShardingCore.Sharding
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return _shardingDbContextFactory.Create(ShardingDbContextType, CreateParallelShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
return _shardingDbContextFactory.Create(ShardingDbContextType, CetMonopolyShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,21 +129,6 @@ namespace ShardingCore.Sharding
|
||||||
return GetDbContext(true, tail);
|
return GetDbContext(true, tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SupportMARS()
|
|
||||||
{
|
|
||||||
return _shardingDbContextOptionsBuilderConfig.SupportMARS;
|
|
||||||
}
|
|
||||||
public bool TryOpen()
|
|
||||||
{
|
|
||||||
var dbConnection = Database.GetDbConnection();
|
|
||||||
if (dbConnection.State != ConnectionState.Open)
|
|
||||||
{
|
|
||||||
dbConnection.Open();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry Add(object entity)
|
public override EntityEntry Add(object entity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,9 +34,6 @@ namespace ShardingCore.Sharding.Abstractions
|
||||||
DbContext CreateGenericDbContext<T>(T entity) where T : class;
|
DbContext CreateGenericDbContext<T>(T entity) where T : class;
|
||||||
|
|
||||||
|
|
||||||
bool TryOpen();
|
|
||||||
bool SupportMARS();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IShardingTableDbContext<T> : IShardingDbContext where T : DbContext, IShardingTableDbContext
|
public interface IShardingTableDbContext<T> : IShardingDbContext where T : DbContext, IShardingTableDbContext
|
||||||
|
|
|
@ -16,26 +16,25 @@ namespace ShardingCore.Sharding
|
||||||
*/
|
*/
|
||||||
public class ShardingDbContextOptionsBuilderConfig<TShardingDbContext> : IShardingDbContextOptionsBuilderConfig where TShardingDbContext : DbContext, IShardingDbContext
|
public class ShardingDbContextOptionsBuilderConfig<TShardingDbContext> : IShardingDbContextOptionsBuilderConfig where TShardingDbContext : DbContext, IShardingDbContext
|
||||||
{
|
{
|
||||||
public ShardingDbContextOptionsBuilderConfig(Action<DbConnection, DbContextOptionsBuilder> shardingDbContextConnectionOptionsCreator,Action<string, DbContextOptionsBuilder> shardingDbContextStringionOptionsCreator)
|
public ShardingDbContextOptionsBuilderConfig(Action<DbConnection, DbContextOptionsBuilder> sameConnectionDbContextOptionsCreator, Action<DbContextOptionsBuilder> defaultQueryDbContextOptionsCreator)
|
||||||
{
|
{
|
||||||
ShardingDbContextConnectionOptionsCreator = shardingDbContextConnectionOptionsCreator;
|
SameConnectionDbContextOptionsCreator = sameConnectionDbContextOptionsCreator;
|
||||||
ShardingDbContextStringOptionsCreator = shardingDbContextStringionOptionsCreator;
|
DefaultQueryDbContextOptionsCreator = defaultQueryDbContextOptionsCreator;
|
||||||
}
|
}
|
||||||
public Action<DbConnection, DbContextOptionsBuilder> ShardingDbContextConnectionOptionsCreator { get; }
|
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionDbContextOptionsCreator { get; }
|
||||||
public Action<string, DbContextOptionsBuilder> ShardingDbContextStringOptionsCreator { get; }
|
public Action<DbContextOptionsBuilder> DefaultQueryDbContextOptionsCreator { get; }
|
||||||
public Type ShardingDbContextType => typeof(TShardingDbContext);
|
public Type ShardingDbContextType => typeof(TShardingDbContext);
|
||||||
public bool SupportMARS => ShardingDbContextStringOptionsCreator == null;
|
|
||||||
|
|
||||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder)
|
public DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||||
{
|
{
|
||||||
ShardingDbContextConnectionOptionsCreator(dbConnection, dbContextOptionsBuilder);
|
SameConnectionDbContextOptionsCreator(dbConnection, dbContextOptionsBuilder);
|
||||||
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||||
return dbContextOptionsBuilder;
|
return dbContextOptionsBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString, DbContextOptionsBuilder dbContextOptionsBuilder)
|
public DbContextOptionsBuilder UseDbContextOptionsBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||||
{
|
{
|
||||||
ShardingDbContextStringOptionsCreator(connectionString, dbContextOptionsBuilder);
|
DefaultQueryDbContextOptionsCreator(dbContextOptionsBuilder);
|
||||||
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||||
return dbContextOptionsBuilder;
|
return dbContextOptionsBuilder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using ShardingCore.Core.ShardingAccessors;
|
||||||
|
|
||||||
|
|
||||||
namespace ShardingCore.Sharding
|
namespace ShardingCore.Sharding
|
||||||
|
@ -23,6 +24,7 @@ namespace ShardingCore.Sharding
|
||||||
private readonly IQueryable<T> _source;
|
private readonly IQueryable<T> _source;
|
||||||
private readonly IShardingDbContext _shardingDbContext;
|
private readonly IShardingDbContext _shardingDbContext;
|
||||||
private readonly IRoutingRuleEngineFactory _tableRoutingRuleEngineFactory;
|
private readonly IRoutingRuleEngineFactory _tableRoutingRuleEngineFactory;
|
||||||
|
private readonly IShardingScopeFactory _shardingScopeFactory;
|
||||||
|
|
||||||
private readonly IQueryable<T> _reWriteSource;
|
private readonly IQueryable<T> _reWriteSource;
|
||||||
//public IEnumerable<RouteResult> RouteResults { get; }
|
//public IEnumerable<RouteResult> RouteResults { get; }
|
||||||
|
@ -34,12 +36,13 @@ namespace ShardingCore.Sharding
|
||||||
public SelectContext SelectContext { get;}
|
public SelectContext SelectContext { get;}
|
||||||
public GroupByContext GroupByContext { get; }
|
public GroupByContext GroupByContext { get; }
|
||||||
|
|
||||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory)
|
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory, IShardingScopeFactory shardingScopeFactory)
|
||||||
{
|
{
|
||||||
//_shardingScopeFactory = shardingScopeFactory;
|
//_shardingScopeFactory = shardingScopeFactory;
|
||||||
_source = source;
|
_source = source;
|
||||||
_shardingDbContext = shardingDbContext;
|
_shardingDbContext = shardingDbContext;
|
||||||
_tableRoutingRuleEngineFactory = tableRoutingRuleEngineFactory;
|
_tableRoutingRuleEngineFactory = tableRoutingRuleEngineFactory;
|
||||||
|
_shardingScopeFactory = shardingScopeFactory;
|
||||||
var reWriteResult = new ReWriteEngine<T>(source).ReWrite();
|
var reWriteResult = new ReWriteEngine<T>(source).ReWrite();
|
||||||
Skip = reWriteResult.Skip;
|
Skip = reWriteResult.Skip;
|
||||||
Take = reWriteResult.Take;
|
Take = reWriteResult.Take;
|
||||||
|
@ -64,28 +67,19 @@ namespace ShardingCore.Sharding
|
||||||
// _reWriteSource = reWriteResult.ReWriteQueryable;
|
// _reWriteSource = reWriteResult.ReWriteQueryable;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public bool TryOpen()
|
public DbContext CreateDbContext(string tail)
|
||||||
{
|
{
|
||||||
return _shardingDbContext.TryOpen();
|
return _shardingDbContext.GetDbContext(false, tail);
|
||||||
}
|
|
||||||
|
|
||||||
public bool SupportMARS()
|
|
||||||
{
|
|
||||||
return _shardingDbContext.SupportMARS();
|
|
||||||
}
|
|
||||||
public DbContext CreateDbContext(bool track,string tail)
|
|
||||||
{
|
|
||||||
return _shardingDbContext.GetDbContext(track, tail);
|
|
||||||
}
|
}
|
||||||
public IEnumerable<RouteResult> GetRouteResults()
|
public IEnumerable<RouteResult> GetRouteResults()
|
||||||
{
|
{
|
||||||
return _tableRoutingRuleEngineFactory.Route(_shardingDbContext.GetType(),_source);
|
return _tableRoutingRuleEngineFactory.Route(_shardingDbContext.GetType(),_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
//public ShardingScope CreateScope()
|
public ShardingScope CreateScope()
|
||||||
//{
|
{
|
||||||
// return _shardingScopeFactory.CreateScope();
|
return _shardingScopeFactory.CreateScope();
|
||||||
//}
|
}
|
||||||
|
|
||||||
public IQueryable<T> GetReWriteQueryable()
|
public IQueryable<T> GetReWriteQueryable()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using ShardingCore.Core.ShardingAccessors;
|
||||||
|
|
||||||
namespace ShardingCore.Sharding
|
namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
|
@ -13,15 +14,17 @@ namespace ShardingCore.Sharding
|
||||||
public class StreamMergeContextFactory:IStreamMergeContextFactory
|
public class StreamMergeContextFactory:IStreamMergeContextFactory
|
||||||
{
|
{
|
||||||
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
||||||
|
private readonly IShardingScopeFactory _shardingScopeFactory;
|
||||||
|
|
||||||
public StreamMergeContextFactory(
|
public StreamMergeContextFactory(
|
||||||
IRoutingRuleEngineFactory routingRuleEngineFactory)
|
IRoutingRuleEngineFactory routingRuleEngineFactory,IShardingScopeFactory shardingScopeFactory)
|
||||||
{
|
{
|
||||||
_routingRuleEngineFactory = routingRuleEngineFactory;
|
_routingRuleEngineFactory = routingRuleEngineFactory;
|
||||||
|
_shardingScopeFactory = shardingScopeFactory;
|
||||||
}
|
}
|
||||||
public StreamMergeContext<T> Create<T>(IQueryable<T> queryable,IShardingDbContext shardingDbContext)
|
public StreamMergeContext<T> Create<T>(IQueryable<T> queryable,IShardingDbContext shardingDbContext)
|
||||||
{
|
{
|
||||||
return new StreamMergeContext<T>(queryable,shardingDbContext, _routingRuleEngineFactory);
|
return new StreamMergeContext<T>(queryable,shardingDbContext, _routingRuleEngineFactory, _shardingScopeFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using ShardingCore.Core.ShardingAccessors;
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
using ShardingCore.Exceptions;
|
using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
|
@ -22,7 +23,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
||||||
* @Ver: 1.0
|
* @Ver: 1.0
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractInMemoryAsyncMergeEngine<TEntity>: IInMemoryAsyncMergeEngine<TEntity>
|
public abstract class AbstractInMemoryAsyncMergeEngine<TEntity> : IInMemoryAsyncMergeEngine<TEntity>
|
||||||
{
|
{
|
||||||
private readonly MethodCallExpression _methodCallExpression;
|
private readonly MethodCallExpression _methodCallExpression;
|
||||||
private readonly StreamMergeContext<TEntity> _mergeContext;
|
private readonly StreamMergeContext<TEntity> _mergeContext;
|
||||||
|
@ -53,7 +54,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
||||||
{
|
{
|
||||||
|
|
||||||
#if !EFCORE2
|
#if !EFCORE2
|
||||||
throw new InvalidOperationException(methodCallExpression.Print());
|
throw new InvalidOperationException(methodCallExpression.Print());
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2
|
#if EFCORE2
|
||||||
throw new InvalidOperationException(methodCallExpression.ToString());
|
throw new InvalidOperationException(methodCallExpression.ToString());
|
||||||
|
@ -62,26 +63,36 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
||||||
}
|
}
|
||||||
|
|
||||||
_mergeContext = ShardingContainer.GetService<IStreamMergeContextFactory>().Create(_queryable, shardingDbContext);
|
_mergeContext = ShardingContainer.GetService<IStreamMergeContextFactory>().Create(_queryable, shardingDbContext);
|
||||||
_mergeContext.TryOpen();
|
|
||||||
_parllelDbbContexts = new List<DbContext>();
|
_parllelDbbContexts = new List<DbContext>();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IQueryable<TEntity> ProcessSecondExpression(IQueryable<TEntity> queryable, Expression secondExpression);
|
protected abstract IQueryable<TEntity> ProcessSecondExpression(IQueryable<TEntity> queryable, Expression secondExpression);
|
||||||
|
|
||||||
public async Task<List<TResult>> ExecuteAsync<TResult>(Func<IQueryable, Task<TResult>> efQuery,CancellationToken cancellationToken = new CancellationToken())
|
public async Task<List<TResult>> ExecuteAsync<TResult>(Func<IQueryable, Task<TResult>> efQuery, CancellationToken cancellationToken = new CancellationToken())
|
||||||
{
|
{
|
||||||
var enumeratorTasks = GetRouteDbContext().Select(shardingDbContext =>
|
var tableResult = _mergeContext.GetRouteResults();
|
||||||
|
var enumeratorTasks = tableResult.Select(routeResult =>
|
||||||
{
|
{
|
||||||
|
if (routeResult.ReplaceTables.Count > 1)
|
||||||
|
throw new ShardingCoreException("route found more than 1 table name s");
|
||||||
|
var tail = string.Empty;
|
||||||
|
if (routeResult.ReplaceTables.Count == 1)
|
||||||
|
tail = routeResult.ReplaceTables.First().Tail;
|
||||||
|
|
||||||
return Task.Run(async () =>
|
return Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//using (var scope = _mergeContext.CreateScope())
|
||||||
|
//{
|
||||||
|
// scope.ShardingAccessor.ShardingContext = ShardingContext.Create(routeResult);
|
||||||
|
var shardingDbContext = _mergeContext.CreateDbContext(tail);
|
||||||
|
_parllelDbbContexts.Add(shardingDbContext);
|
||||||
var newQueryable = (IQueryable<TEntity>)GetStreamMergeContext().GetReWriteQueryable()
|
var newQueryable = (IQueryable<TEntity>)GetStreamMergeContext().GetReWriteQueryable()
|
||||||
.ReplaceDbContextQueryable(shardingDbContext);
|
.ReplaceDbContextQueryable(shardingDbContext);
|
||||||
var newFilterQueryable=EFQueryAfterFilter<TResult>(newQueryable);
|
var newFilterQueryable = EFQueryAfterFilter<TResult>(newQueryable);
|
||||||
var query = await efQuery(newFilterQueryable);
|
return await efQuery(newFilterQueryable);
|
||||||
return query;
|
//}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -91,62 +102,52 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
||||||
});
|
});
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
return (await Task.WhenAll(enumeratorTasks)).ToList();
|
return (await Task.WhenAll(enumeratorTasks)).ToList();
|
||||||
}
|
}
|
||||||
public List<TResult> Execute<TResult>(Func<IQueryable, TResult> efQuery, CancellationToken cancellationToken = new CancellationToken())
|
public List<TResult> Execute<TResult>(Func<IQueryable, TResult> efQuery, CancellationToken cancellationToken = new CancellationToken())
|
||||||
{
|
{
|
||||||
var enumeratorTasks = GetRouteDbContext().Select(shardingDbContext =>
|
var tableResult = _mergeContext.GetRouteResults();
|
||||||
|
var enumeratorTasks = tableResult.Select(routeResult =>
|
||||||
{
|
{
|
||||||
|
if (routeResult.ReplaceTables.Count > 1)
|
||||||
|
throw new ShardingCoreException("route found more than 1 table name s");
|
||||||
|
var tail = string.Empty;
|
||||||
|
if (routeResult.ReplaceTables.Count == 1)
|
||||||
|
tail = routeResult.ReplaceTables.First().Tail;
|
||||||
|
|
||||||
return Task.Run( () =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var newQueryable = (IQueryable<TEntity>)GetStreamMergeContext().GetReWriteQueryable()
|
//using (var scope = _mergeContext.CreateScope())
|
||||||
.ReplaceDbContextQueryable(shardingDbContext);
|
//{
|
||||||
var newFilterQueryable = EFQueryAfterFilter<TResult>(newQueryable);
|
// scope.ShardingAccessor.ShardingContext = ShardingContext.Create(routeResult);
|
||||||
var query = efQuery(newFilterQueryable);
|
var shardingDbContext = _mergeContext.CreateDbContext(tail);
|
||||||
return query;
|
_parllelDbbContexts.Add(shardingDbContext);
|
||||||
}
|
var newQueryable = (IQueryable<TEntity>)GetStreamMergeContext().GetReWriteQueryable()
|
||||||
catch (Exception e)
|
.ReplaceDbContextQueryable(shardingDbContext);
|
||||||
{
|
var newFilterQueryable = EFQueryAfterFilter<TResult>(newQueryable);
|
||||||
Console.WriteLine(e);
|
var query = efQuery(newFilterQueryable);
|
||||||
throw;
|
return query;
|
||||||
}
|
//}
|
||||||
});
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
});
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
return Task.WhenAll(enumeratorTasks).GetAwaiter().GetResult().ToList();
|
return Task.WhenAll(enumeratorTasks).GetAwaiter().GetResult().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbContext[] GetRouteDbContext()
|
|
||||||
{
|
|
||||||
|
|
||||||
var tableResult = _mergeContext.GetRouteResults();
|
|
||||||
return tableResult.Select(routeResult =>
|
|
||||||
{
|
|
||||||
var tail = CheckAndGetTail(routeResult);
|
|
||||||
var shardingDbContext = _mergeContext.CreateDbContext(tableResult.Count() == 1, tail);
|
|
||||||
if (!_mergeContext.SupportMARS())
|
|
||||||
_parllelDbbContexts.Add(shardingDbContext);
|
|
||||||
return shardingDbContext;
|
|
||||||
}).ToArray();
|
|
||||||
}
|
|
||||||
private string CheckAndGetTail(RouteResult routeResult)
|
|
||||||
{
|
|
||||||
if (routeResult.ReplaceTables.Count > 1)
|
|
||||||
throw new ShardingCoreException("route found more than 1 table name s");
|
|
||||||
var tail = string.Empty;
|
|
||||||
if (routeResult.ReplaceTables.Count == 1)
|
|
||||||
tail = routeResult.ReplaceTables.First().Tail;
|
|
||||||
return tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual IQueryable EFQueryAfterFilter<TResult>(IQueryable<TEntity> queryable)
|
public virtual IQueryable EFQueryAfterFilter<TResult>(IQueryable<TEntity> queryable)
|
||||||
{
|
{
|
||||||
return queryable;
|
return queryable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StreamMergeContext<TEntity> GetStreamMergeContext()
|
public StreamMergeContext<TEntity> GetStreamMergeContext()
|
||||||
{
|
{
|
||||||
return _mergeContext;
|
return _mergeContext;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ShardingCore.Core.ShardingAccessors;
|
||||||
using ShardingCore.Exceptions;
|
using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
using ShardingCore.Sharding.Enumerators;
|
using ShardingCore.Sharding.Enumerators;
|
||||||
|
@ -72,18 +73,29 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
||||||
|
|
||||||
private IAsyncEnumerator<T> GetShardingEnumerator()
|
private IAsyncEnumerator<T> GetShardingEnumerator()
|
||||||
{
|
{
|
||||||
var enumeratorTasks = GetRouteDbContext().Select(shardingDbContext =>
|
var tableResult = _mergeContext.GetRouteResults();
|
||||||
|
var enumeratorTasks = tableResult.Select(routeResult =>
|
||||||
{
|
{
|
||||||
|
if (routeResult.ReplaceTables.Count > 1)
|
||||||
|
throw new ShardingCoreException("route found more than 1 table name s");
|
||||||
|
var tail = string.Empty;
|
||||||
|
if (routeResult.ReplaceTables.Count == 1)
|
||||||
|
tail = routeResult.ReplaceTables.First().Tail;
|
||||||
return Task.Run(async () =>
|
return Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//using (var scope = _mergeContext.CreateScope())
|
||||||
|
//{
|
||||||
|
// scope.ShardingAccessor.ShardingContext = ShardingContext.Create(routeResult);
|
||||||
|
var shardingDbContext = _mergeContext.CreateDbContext(tail);
|
||||||
|
_parllelDbbContexts.Add(shardingDbContext);
|
||||||
var newQueryable = (IQueryable<T>)_mergeContext.GetReWriteQueryable()
|
var newQueryable = (IQueryable<T>)_mergeContext.GetReWriteQueryable()
|
||||||
.ReplaceDbContextQueryable(shardingDbContext);
|
.ReplaceDbContextQueryable(shardingDbContext);
|
||||||
|
|
||||||
var asyncEnumerator = await GetAsyncEnumerator(newQueryable);
|
var asyncEnumerator = await GetAsyncEnumerator(newQueryable);
|
||||||
return new StreamMergeAsyncEnumerator<T>(asyncEnumerator);
|
return new StreamMergeAsyncEnumerator<T>(asyncEnumerator);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -109,37 +121,32 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
||||||
return enumator;
|
return enumator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbContext[] GetRouteDbContext()
|
public IEnumerator<T> GetEnumerator()
|
||||||
{
|
{
|
||||||
|
|
||||||
var tableResult = _mergeContext.GetRouteResults();
|
var tableResult = _mergeContext.GetRouteResults();
|
||||||
return tableResult.Select(routeResult =>
|
var enumeratorTasks = tableResult.Select(routeResult =>
|
||||||
{
|
{
|
||||||
if (routeResult.ReplaceTables.Count > 1)
|
if (routeResult.ReplaceTables.Count > 1)
|
||||||
throw new ShardingCoreException("route found more than 1 table name s");
|
throw new ShardingCoreException("route found more than 1 table name s");
|
||||||
var tail = string.Empty;
|
var tail = string.Empty;
|
||||||
if (routeResult.ReplaceTables.Count == 1)
|
if (routeResult.ReplaceTables.Count == 1)
|
||||||
tail = routeResult.ReplaceTables.First().Tail;
|
tail = routeResult.ReplaceTables.First().Tail;
|
||||||
var shardingDbContext = _mergeContext.CreateDbContext(tableResult.Count() == 1, tail);
|
|
||||||
if (!_mergeContext.SupportMARS())
|
|
||||||
_parllelDbbContexts.Add(shardingDbContext);
|
|
||||||
return shardingDbContext;
|
|
||||||
}).ToArray();
|
|
||||||
}
|
|
||||||
public IEnumerator<T> GetEnumerator()
|
|
||||||
{
|
|
||||||
var enumeratorTasks = GetRouteDbContext().Select(shardingDbContext =>
|
|
||||||
{
|
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
//using (var scope = _mergeContext.CreateScope())
|
||||||
|
//{
|
||||||
|
// scope.ShardingAccessor.ShardingContext = ShardingContext.Create(routeResult);
|
||||||
|
var shardingDbContext = _mergeContext.CreateDbContext(tail);
|
||||||
|
_parllelDbbContexts.Add(shardingDbContext);
|
||||||
|
|
||||||
var newQueryable = (IQueryable<T>)_mergeContext.GetReWriteQueryable()
|
var newQueryable = (IQueryable<T>)_mergeContext.GetReWriteQueryable()
|
||||||
.ReplaceDbContextQueryable(shardingDbContext);
|
.ReplaceDbContextQueryable(shardingDbContext);
|
||||||
|
|
||||||
var enumerator = GetEnumerator(newQueryable);
|
var enumerator = GetEnumerator(newQueryable);
|
||||||
return new StreamMergeEnumerator<T>(enumerator);
|
return new StreamMergeEnumerator<T>(enumerator);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,17 +26,17 @@ namespace ShardingCore
|
||||||
private readonly Dictionary<Type, Type> _virtualRoutes = new Dictionary<Type, Type>();
|
private readonly Dictionary<Type, Type> _virtualRoutes = new Dictionary<Type, Type>();
|
||||||
|
|
||||||
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionConfigure { get; set; }
|
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionConfigure { get; set; }
|
||||||
public Action<string, DbContextOptionsBuilder> NotSupportMARSConfigure { get; set; }
|
public Action<DbContextOptionsBuilder> DefaultQueryConfigure { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配置如何创建对应的dbcontext来操作数据如果数据库支持mars则仅需配置sameConnectionConfigure无需配置notSupportMARSConfigure如果配置了notSupportMARSConfigure则表示数据库不支持MARS则查询将无法正常追踪需要手动attach
|
/// 配置数据库分表查询和保存时的DbContext创建方式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sameConnectionConfigure">dbconnection下如何配置</param>
|
/// <param name="sameConnectionConfigure">DbConnection下如何配置因为不同的DbContext支持事务需要使用同一个DbConnection</param>
|
||||||
/// <param name="notSupportMARSConfigure">链接字符串下如何配置</param>
|
/// <param name="defaultBuilderConfigure">默认查询DbContext创建的配置</param>
|
||||||
|
|
||||||
public void UseShardingOptionsBuilder(Action<DbConnection, DbContextOptionsBuilder> sameConnectionConfigure, Action<string, DbContextOptionsBuilder> notSupportMARSConfigure = null)
|
public void UseShardingOptionsBuilder(Action<DbConnection, DbContextOptionsBuilder> sameConnectionConfigure, Action<DbContextOptionsBuilder> defaultQueryConfigure = null)
|
||||||
{
|
{
|
||||||
SameConnectionConfigure = sameConnectionConfigure??throw new ArgumentNullException(nameof(sameConnectionConfigure));
|
SameConnectionConfigure = sameConnectionConfigure ?? throw new ArgumentNullException(nameof(sameConnectionConfigure));
|
||||||
NotSupportMARSConfigure = notSupportMARSConfigure;
|
DefaultQueryConfigure = defaultQueryConfigure ?? throw new ArgumentNullException(nameof(defaultQueryConfigure));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,6 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\ShardingCore.MySql\ShardingCore.MySql.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Configs\DbConfig.json">
|
<Content Include="Configs\DbConfig.json">
|
||||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
@ -28,4 +24,8 @@
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src3x\ShardingCore.3x\ShardingCore.3x.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"SqlServer": {
|
"SqlServer": {
|
||||||
"ConnectionString": "Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True"
|
"ConnectionString": "Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -20,12 +20,10 @@ namespace ShardingCore.Test50
|
||||||
public class ShardingTest
|
public class ShardingTest
|
||||||
{
|
{
|
||||||
private readonly ShardingDefaultDbContext _virtualDbContext;
|
private readonly ShardingDefaultDbContext _virtualDbContext;
|
||||||
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
|
||||||
|
|
||||||
public ShardingTest(ShardingDefaultDbContext virtualDbContext, IRoutingRuleEngineFactory routingRuleEngineFactory)
|
public ShardingTest(ShardingDefaultDbContext virtualDbContext)
|
||||||
{
|
{
|
||||||
_virtualDbContext = virtualDbContext;
|
_virtualDbContext = virtualDbContext;
|
||||||
_routingRuleEngineFactory = routingRuleEngineFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Fact]
|
//[Fact]
|
||||||
|
@ -72,29 +70,32 @@ namespace ShardingCore.Test50
|
||||||
//[Fact]
|
//[Fact]
|
||||||
//public async Task ToList_Join_Test()
|
//public async Task ToList_Join_Test()
|
||||||
//{
|
//{
|
||||||
// var list = await (from u in _virtualDbContext.Set<SysUserMod>()
|
// var list = await (from u in _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="1" || o.Id=="1000")
|
||||||
// join salary in _virtualDbContext.Set<SysUserSalary>()
|
// join salary in _virtualDbContext.Set<SysUserSalary>()
|
||||||
// on u.Id equals salary.UserId
|
// on u.Id equals salary.UserId
|
||||||
// select new
|
// select new
|
||||||
// {
|
// {
|
||||||
// Salary = salary.Salary,
|
// u.Id,
|
||||||
// DateOfMonth = salary.DateOfMonth,
|
// u.Age,
|
||||||
// Name = u.Name
|
// Salary = salary.Salary,
|
||||||
// }).ToShardingListAsync();
|
// DateOfMonth = salary.DateOfMonth,
|
||||||
|
// Name = u.Name
|
||||||
|
// }).ToListAsync();
|
||||||
|
// var list2 = list.OrderBy(o=>o.Age).ToList();
|
||||||
// Assert.Equal(24000, list.Count());
|
// Assert.Equal(24000, list.Count());
|
||||||
// Assert.Equal(24, list.Count(o => o.Name == "name_200"));
|
// Assert.Equal(24, list.Count(o => o.Name == "name_200"));
|
||||||
|
|
||||||
|
|
||||||
// var queryable = (from u in _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "300")
|
// var queryable = (from u in _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "300")
|
||||||
// join salary in _virtualDbContext.Set<SysUserSalary>()
|
// join salary in _virtualDbContext.Set<SysUserSalary>()
|
||||||
// on u.Id equals salary.UserId
|
// on u.Id equals salary.UserId
|
||||||
// select new
|
// select new
|
||||||
// {
|
// {
|
||||||
// Salary = salary.Salary,
|
// Salary = salary.Salary,
|
||||||
// DateOfMonth = salary.DateOfMonth,
|
// DateOfMonth = salary.DateOfMonth,
|
||||||
// Name = u.Name
|
// Name = u.Name
|
||||||
// });
|
// });
|
||||||
// var list1 = await queryable.ToShardingListAsync();
|
// var list1 = await queryable.ToListAsync();
|
||||||
// Assert.Equal(24, list1.Count());
|
// Assert.Equal(24, list1.Count());
|
||||||
// Assert.DoesNotContain(list1, o => o.Name != "name_300");
|
// Assert.DoesNotContain(list1, o => o.Name != "name_300");
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -47,15 +47,15 @@ namespace ShardingCore.Test50
|
||||||
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
|
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
|
||||||
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
||||||
{
|
{
|
||||||
|
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"])
|
||||||
|
|
||||||
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;MultipleActiveResultSets=True;")
|
|
||||||
,op =>
|
,op =>
|
||||||
{
|
{
|
||||||
op.EnsureCreatedWithOutShardingTable = true;
|
op.EnsureCreatedWithOutShardingTable = false;
|
||||||
op.CreateShardingTableOnStart = true;
|
op.CreateShardingTableOnStart = false;
|
||||||
op.UseShardingConnStrOptions((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger));
|
op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),
|
||||||
|
builder=> builder.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]).UseLoggerFactory(efLogger));
|
||||||
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||||
|
op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,45 +78,48 @@ namespace ShardingCore.Test50
|
||||||
using (var scope = serviceProvider.CreateScope())
|
using (var scope = serviceProvider.CreateScope())
|
||||||
{
|
{
|
||||||
var virtualDbContext = scope.ServiceProvider.GetService<ShardingDefaultDbContext>();
|
var virtualDbContext = scope.ServiceProvider.GetService<ShardingDefaultDbContext>();
|
||||||
var ids = Enumerable.Range(1, 1000);
|
if (!await virtualDbContext.Set<SysUserMod>().AnyAsync())
|
||||||
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()
|
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)
|
||||||
{
|
{
|
||||||
Id = id.ToString(),
|
userMods.Add(new SysUserMod()
|
||||||
Age = 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}",
|
Id = id.ToString(),
|
||||||
UserId = id.ToString(),
|
Age = id,
|
||||||
DateOfMonth = int.Parse(dateOfMonth),
|
Name = $"name_{id}",
|
||||||
Salary = 700000 + id * 100 * i,
|
AgeGroup = Math.Abs(id % 10)
|
||||||
SalaryLong = 700000 + id * 100 * i,
|
|
||||||
SalaryDecimal = (700000 + id * 100 * i) / 100m,
|
|
||||||
SalaryDouble = (700000 + id * 100 * i) / 100d,
|
|
||||||
SalaryFloat = (700000 + id * 100 * i) / 100f
|
|
||||||
});
|
});
|
||||||
tempTime = tempTime.AddMonths(1);
|
var tempTime = beginTime;
|
||||||
i++;
|
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,
|
||||||
|
SalaryLong = 700000 + id * 100 * i,
|
||||||
|
SalaryDecimal = (700000 + id * 100 * i) / 100m,
|
||||||
|
SalaryDouble = (700000 + id * 100 * i) / 100d,
|
||||||
|
SalaryFloat = (700000 + id * 100 * i) / 100f
|
||||||
|
});
|
||||||
|
tempTime = tempTime.AddMonths(1);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await virtualDbContext.AddRangeAsync(userMods);
|
||||||
|
await virtualDbContext.AddRangeAsync(userSalaries);
|
||||||
|
|
||||||
|
await virtualDbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
await virtualDbContext.AddRangeAsync(userMods);
|
|
||||||
await virtualDbContext.AddRangeAsync(userSalaries);
|
|
||||||
|
|
||||||
await virtualDbContext.SaveChangesAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
|
||||||
using ShardingCore.Sharding.Abstractions;
|
|
||||||
using ShardingCoreTestBatch.Domain.Maps;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestBatch
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: 2021/3/31 15:28:11
|
|
||||||
* @Ver: 1.0
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class DefaultDbContext : DbContext, IShardingTableDbContext
|
|
||||||
{
|
|
||||||
public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
base.OnModelCreating(modelBuilder);
|
|
||||||
modelBuilder.ApplyConfiguration(new SysUserModMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ModelChangeKey { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
using ShardingCore.Core;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestBatch.Domain.Entities
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Thursday, 14 January 2021 15:36:43
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserMod:IShardingTable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用户Id用于分表
|
|
||||||
/// </summary>
|
|
||||||
[ShardingTableKey(TailPrefix = "_")]
|
|
||||||
public string Id { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 用户名称
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 用户姓名
|
|
||||||
/// </summary>
|
|
||||||
public int Age { get; set; }
|
|
||||||
public int AgeGroup { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
||||||
using ShardingCoreTestBatch.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestBatch.Domain.Maps
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Thursday, 14 January 2021 15:37:33
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserModMap:IEntityTypeConfiguration<SysUserMod>
|
|
||||||
{
|
|
||||||
public void Configure(EntityTypeBuilder<SysUserMod> builder)
|
|
||||||
{
|
|
||||||
builder.HasKey(o => o.Id);
|
|
||||||
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
|
||||||
builder.Property(o => o.Name).HasMaxLength(128);
|
|
||||||
builder.ToTable(nameof(SysUserMod));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
|
||||||
<LangVersion>9.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="Configs\**" />
|
|
||||||
<EmbeddedResource Remove="Configs\**" />
|
|
||||||
<None Remove="Configs\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.2" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
|
||||||
<PackageReference Include="Xunit.DependencyInjection" Version="7.1.0" />
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="5.1.29" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\ShardingCore.SqlServer\ShardingCore.SqlServer.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,58 +0,0 @@
|
||||||
// using System;
|
|
||||||
// using System.Diagnostics;
|
|
||||||
// using System.Linq;
|
|
||||||
// using System.Threading.Tasks;
|
|
||||||
// using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
|
||||||
// using ShardingCore.DbContexts.VirtualDbContexts;
|
|
||||||
// using ShardingCore.Extensions;
|
|
||||||
// using ShardingCoreTestBatch.Domain.Entities;
|
|
||||||
// using Xunit;
|
|
||||||
//
|
|
||||||
// namespace ShardingCoreTestBatch
|
|
||||||
// {
|
|
||||||
// /*
|
|
||||||
// * @Author: xjm
|
|
||||||
// * @Description:
|
|
||||||
// * @Date: Friday, 15 January 2021 17:22:10
|
|
||||||
// * @Email: 326308290@qq.com
|
|
||||||
// */
|
|
||||||
// public class ShardingTest
|
|
||||||
// {
|
|
||||||
// private readonly IVirtualDbContext _virtualDbContext;
|
|
||||||
// private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
|
||||||
//
|
|
||||||
// public ShardingTest(IVirtualDbContext virtualDbContext,IRoutingRuleEngineFactory routingRuleEngineFactory)
|
|
||||||
// {
|
|
||||||
// _virtualDbContext = virtualDbContext;
|
|
||||||
// _routingRuleEngineFactory = routingRuleEngineFactory;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //[Fact]
|
|
||||||
// //public async Task Route_TEST()
|
|
||||||
// //{
|
|
||||||
// // var queryable1 = _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="339");
|
|
||||||
// // var routeResults1 = _routingRuleEngineFactory.Route(queryable1);
|
|
||||||
// // Assert.Equal(1,routeResults1.Count());
|
|
||||||
// // Assert.Equal(1,routeResults1.FirstOrDefault().ReplaceTables.Count());
|
|
||||||
// // Assert.Equal("0",routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().Tail);
|
|
||||||
// // Assert.Equal(nameof(SysUserMod),routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().OriginalName);
|
|
||||||
// // var ids = new[] {"339", "124","142"};
|
|
||||||
// // var queryable2= _virtualDbContext.Set<SysUserMod>().Where(o=>ids.Contains(o.Id));
|
|
||||||
// // var routeResult2s = _routingRuleEngineFactory.Route(queryable2);
|
|
||||||
// // Assert.Equal(2,routeResult2s.Count());
|
|
||||||
// // Assert.Equal(1,routeResult2s.FirstOrDefault().ReplaceTables.Count());
|
|
||||||
// // Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count());
|
|
||||||
// // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail)));
|
|
||||||
// //}
|
|
||||||
// [Fact]
|
|
||||||
// public async Task ToList_All_Test()
|
|
||||||
// {
|
|
||||||
// var startNew = Stopwatch.StartNew(); startNew.Start();
|
|
||||||
// var mods = await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Age== 7601935).ToShardingListAsync();
|
|
||||||
// startNew.Stop();
|
|
||||||
// var x = startNew.ElapsedMilliseconds;
|
|
||||||
// Console.WriteLine(mods.Count);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
|
@ -1,19 +0,0 @@
|
||||||
using ShardingCore.VirtualRoutes.Mods;
|
|
||||||
using ShardingCoreTestBatch.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestBatch.Shardings
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Thursday, 14 January 2021 15:39:27
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
|
|
||||||
{
|
|
||||||
public SysUserModVirtualTableRoute() : base(2,15)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
// using System;
|
|
||||||
// using System.Collections.Generic;
|
|
||||||
// using System.Linq;
|
|
||||||
// using System.Text.RegularExpressions;
|
|
||||||
// using System.Threading.Tasks;
|
|
||||||
// using Microsoft.EntityFrameworkCore;
|
|
||||||
// using Microsoft.Extensions.Configuration;
|
|
||||||
// using Microsoft.Extensions.DependencyInjection;
|
|
||||||
// using Microsoft.Extensions.Hosting;
|
|
||||||
// using ShardingCore;
|
|
||||||
// using ShardingCore.DbContexts.VirtualDbContexts;
|
|
||||||
// using ShardingCore.Extensions;
|
|
||||||
// using ShardingCore.SqlServer;
|
|
||||||
// using ShardingCoreTestBatch.Domain.Entities;
|
|
||||||
// using ShardingCoreTestBatch.Shardings;
|
|
||||||
//
|
|
||||||
// #if EFCORE5SQLSERVER
|
|
||||||
// using ShardingCore.SqlServer;
|
|
||||||
// #endif
|
|
||||||
// #if EFCORE5MYSQL
|
|
||||||
// using ShardingCore.MySql;
|
|
||||||
// #endif
|
|
||||||
//
|
|
||||||
// namespace ShardingCoreTestBatch
|
|
||||||
// {
|
|
||||||
// /*
|
|
||||||
// * @Author: xjm
|
|
||||||
// * @Description:
|
|
||||||
// * @Date: Friday, 15 January 2021 15:37:46
|
|
||||||
// * @Email: 326308290@qq.com
|
|
||||||
// */
|
|
||||||
// public class Startup
|
|
||||||
// {
|
|
||||||
// // // 自定义 host 构建
|
|
||||||
// //public void ConfigureHost(IHostBuilder hostBuilder)
|
|
||||||
// //{
|
|
||||||
// // hostBuilder
|
|
||||||
// // .ConfigureAppConfiguration(builder =>
|
|
||||||
// // {
|
|
||||||
// // builder.AddJsonFile("Configs/DbConfig.json");
|
|
||||||
// // });
|
|
||||||
// //}
|
|
||||||
//
|
|
||||||
// // 支持的形式:
|
|
||||||
// // ConfigureServices(IServiceCollection services)
|
|
||||||
// // ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
|
||||||
// // ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
|
|
||||||
// public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// services.AddShardingSqlServer(o =>
|
|
||||||
// {
|
|
||||||
// o.EnsureCreatedWithOutShardingTable = true;
|
|
||||||
// o.CreateShardingTableOnStart = true;
|
|
||||||
// o.UseShardingDbContext<DefaultDbContext>(dbConfig =>
|
|
||||||
// {
|
|
||||||
// dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
|
||||||
// });
|
|
||||||
// //o.AddDataSourceVirtualRoute<>();
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
// //services.AddShardingSqlServer(o =>
|
|
||||||
// //{
|
|
||||||
// // o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
|
|
||||||
// // o.AddSharding<SysUserModVirtualTableRoute>();
|
|
||||||
// // o.AddSharding<SysUserSalaryVirtualTableRoute>();
|
|
||||||
// // o.UseShardingCoreConfig((provider, config) =>
|
|
||||||
// // {
|
|
||||||
// // config.EnsureCreated = true;
|
|
||||||
// // config.CreateShardingTableOnStart = true;
|
|
||||||
// // });
|
|
||||||
// //});
|
|
||||||
//
|
|
||||||
// services.AddDbContext<DefaultDbContext>(o=>o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBBatch;Integrated Security=True"));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法
|
|
||||||
// public void Configure(IServiceProvider serviceProvider)
|
|
||||||
// {
|
|
||||||
// var shardingBootstrapper = serviceProvider.GetService<IShardingBootstrapper>();
|
|
||||||
// shardingBootstrapper.Start();
|
|
||||||
// // 有一些测试数据要初始化可以放在这里
|
|
||||||
// InitData(serviceProvider).GetAwaiter().GetResult();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /// <summary>
|
|
||||||
// /// 添加种子数据
|
|
||||||
// /// </summary>
|
|
||||||
// /// <param name="serviceProvider"></param>
|
|
||||||
// /// <returns></returns>
|
|
||||||
// private async Task InitData(IServiceProvider serviceProvider)
|
|
||||||
// {
|
|
||||||
// using (var scope = serviceProvider.CreateScope())
|
|
||||||
// {
|
|
||||||
// var virtualDbContext = scope.ServiceProvider.GetService<DefaultDbContext>();
|
|
||||||
// if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => true))
|
|
||||||
// {
|
|
||||||
// var ids = Enumerable.Range(1, 9000000);
|
|
||||||
// var userMods = new List<SysUserMod>();
|
|
||||||
// foreach (var id in ids)
|
|
||||||
// {
|
|
||||||
// userMods.Add(new SysUserMod()
|
|
||||||
// {
|
|
||||||
// Id = id.ToString(),
|
|
||||||
// Age = id,
|
|
||||||
// Name = $"name_{id}",
|
|
||||||
// AgeGroup=Math.Abs(id%10)
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// //
|
|
||||||
// // var shardingBatchInsertEntry = virtualDbContext.BulkInsert(userMods);
|
|
||||||
// // shardingBatchInsertEntry.BatchGroups.ForEach(g =>
|
|
||||||
// // {
|
|
||||||
// // g.Key.BulkInsert(g.Value);
|
|
||||||
// // });
|
|
||||||
//
|
|
||||||
// await virtualDbContext.SaveChangesAsync();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"SqlServer": {
|
|
||||||
"ConnectionString": "Data Source=localhost;Initial Catalog=ShardingCoreDB3x;Integrated Security=True"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
|
||||||
using ShardingCore.Sharding.Abstractions;
|
|
||||||
using ShardingCoreTestSqlServer3x.Domain.Maps;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: 2021/3/31 15:28:11
|
|
||||||
* @Ver: 1.0
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class DefaultDbContext : DbContext, IShardingTableDbContext
|
|
||||||
{
|
|
||||||
public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
base.OnModelCreating(modelBuilder);
|
|
||||||
modelBuilder.ApplyConfiguration(new SysUserModMap());
|
|
||||||
modelBuilder.ApplyConfiguration(new SysUserSalaryMap());
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ModelChangeKey { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
using ShardingCore.Core;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x.Domain.Entities
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Thursday, 14 January 2021 15:36:43
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserMod:IShardingTable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用户Id用于分表
|
|
||||||
/// </summary>
|
|
||||||
[ShardingTableKey]
|
|
||||||
public string Id { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 用户名称
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 用户姓名
|
|
||||||
/// </summary>
|
|
||||||
public int Age { get; set; }
|
|
||||||
public int AgeGroup { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
using ShardingCore.Core;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x.Domain.Entities
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Monday, 01 February 2021 15:43:22
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserSalary:IShardingTable
|
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
public string UserId { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 每月的金额
|
|
||||||
/// </summary>
|
|
||||||
[ShardingTableKey]
|
|
||||||
public int DateOfMonth { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 工资
|
|
||||||
/// </summary>
|
|
||||||
public int Salary { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 工资
|
|
||||||
/// </summary>
|
|
||||||
public long SalaryLong { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 工资
|
|
||||||
/// </summary>
|
|
||||||
public decimal SalaryDecimal { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 工资
|
|
||||||
/// </summary>
|
|
||||||
public double SalaryDouble { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 工资
|
|
||||||
/// </summary>
|
|
||||||
public float SalaryFloat { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
||||||
using ShardingCoreTestSqlServer3x.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x.Domain.Maps
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Thursday, 14 January 2021 15:37:33
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserModMap:IEntityTypeConfiguration<SysUserMod>
|
|
||||||
{
|
|
||||||
public void Configure(EntityTypeBuilder<SysUserMod> builder)
|
|
||||||
{
|
|
||||||
builder.HasKey(o => o.Id);
|
|
||||||
builder.Property(o => o.Id).IsRequired().HasMaxLength(128);
|
|
||||||
builder.Property(o => o.Name).HasMaxLength(128);
|
|
||||||
builder.ToTable(nameof(SysUserMod));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
|
||||||
using ShardingCoreTestSqlServer3x.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x.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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
|
||||||
<LangVersion>9.0</LangVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.2" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
|
||||||
<PackageReference Include="Xunit.DependencyInjection" Version="7.1.0" />
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Include="Configs\DbConfig.json">
|
|
||||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
|
||||||
</Content>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src3x\ShardingCore.SqlServer.3x\ShardingCore.SqlServer.3x.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,391 +0,0 @@
|
||||||
// using System;
|
|
||||||
// using System.Linq;
|
|
||||||
// using System.Threading.Tasks;
|
|
||||||
// using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
|
||||||
// using ShardingCore.DbContexts.VirtualDbContexts;
|
|
||||||
// using ShardingCore.Extensions;
|
|
||||||
// using ShardingCoreTestSqlServer3x.Domain.Entities;
|
|
||||||
// using Xunit;
|
|
||||||
//
|
|
||||||
// namespace ShardingCoreTestSqlServer3x
|
|
||||||
// {
|
|
||||||
// /*
|
|
||||||
// * @Author: xjm
|
|
||||||
// * @Description:
|
|
||||||
// * @Date: Friday, 15 January 2021 17:22:10
|
|
||||||
// * @Email: 326308290@qq.com
|
|
||||||
// */
|
|
||||||
// public class ShardingTest
|
|
||||||
// {
|
|
||||||
// private readonly DefaultDbContext _virtualDbContext;
|
|
||||||
// private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
|
||||||
//
|
|
||||||
// public ShardingTest(DefaultDbContext virtualDbContext,IRoutingRuleEngineFactory routingRuleEngineFactory)
|
|
||||||
// {
|
|
||||||
// _virtualDbContext = virtualDbContext;
|
|
||||||
// _routingRuleEngineFactory = routingRuleEngineFactory;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// //[Fact]
|
|
||||||
// //public async Task Route_TEST()
|
|
||||||
// //{
|
|
||||||
// // var queryable1 = _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="339");
|
|
||||||
// // var routeResults1 = _routingRuleEngineFactory.Route(queryable1);
|
|
||||||
// // Assert.Equal(1,routeResults1.Count());
|
|
||||||
// // Assert.Equal(1,routeResults1.FirstOrDefault().ReplaceTables.Count());
|
|
||||||
// // Assert.Equal("0",routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().Tail);
|
|
||||||
// // Assert.Equal(nameof(SysUserMod),routeResults1.FirstOrDefault().ReplaceTables.FirstOrDefault().OriginalName);
|
|
||||||
// // var ids = new[] {"339", "124","142"};
|
|
||||||
// // var queryable2= _virtualDbContext.Set<SysUserMod>().Where(o=>ids.Contains(o.Id));
|
|
||||||
// // var routeResult2s = _routingRuleEngineFactory.Route(queryable2);
|
|
||||||
// // Assert.Equal(2,routeResult2s.Count());
|
|
||||||
// // Assert.Equal(1,routeResult2s.FirstOrDefault().ReplaceTables.Count());
|
|
||||||
// // Assert.Equal(2,routeResult2s.SelectMany(o=>o.ReplaceTables).Count());
|
|
||||||
// // Assert.Equal(true,routeResult2s.SelectMany(o=>o.ReplaceTables).All(o=>new[]{"0","1"}.Contains(o.Tail)));
|
|
||||||
// //}
|
|
||||||
// [Fact]
|
|
||||||
// public async Task ToList_All_Test()
|
|
||||||
// {
|
|
||||||
// var mods = await _virtualDbContext.Set<SysUserMod>().ToShardingListAsync();
|
|
||||||
// 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(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(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();
|
|
||||||
// foreach (var id in ids)
|
|
||||||
// {
|
|
||||||
// Assert.Contains(sysUserMods, o => o.Id == id);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// 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();
|
|
||||||
// Assert.Single(mods);
|
|
||||||
// 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(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(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(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();
|
|
||||||
// Assert.Single(mods);
|
|
||||||
// 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();
|
|
||||||
// Assert.Empty(mods);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// [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);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// [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 == "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 == "999");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// [Fact]
|
|
||||||
// public async Task FirstOrDefault2()
|
|
||||||
// {
|
|
||||||
// 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();
|
|
||||||
// Assert.NotNull(sysUserMod);
|
|
||||||
// Assert.Equal("2", sysUserMod.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");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// [Fact]
|
|
||||||
// public async Task FirstOrDefault5()
|
|
||||||
// {
|
|
||||||
// var sysUserMod = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Name == "name_1001").ShardingFirstOrDefaultAsync();
|
|
||||||
// Assert.Null(sysUserMod);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// [Fact]
|
|
||||||
// public async Task Count_Test()
|
|
||||||
// {
|
|
||||||
// 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 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 dateOfMonths = new[] {202111, 202110};
|
|
||||||
// var group = await (from u in _virtualDbContext.Set<SysUserSalary>()
|
|
||||||
// .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth))
|
|
||||||
// group u by new
|
|
||||||
// {
|
|
||||||
// UId = u.UserId
|
|
||||||
// }
|
|
||||||
// into g
|
|
||||||
// select new
|
|
||||||
// {
|
|
||||||
// GroupUserId = g.Key.UId,
|
|
||||||
// Count = g.Count(),
|
|
||||||
// TotalSalary = g.Sum(o => o.Salary),
|
|
||||||
// AvgSalary = g.Average(o => o.Salary),
|
|
||||||
// AvgSalaryDecimal = g.Average(o => o.SalaryDecimal),
|
|
||||||
// MinSalary = g.Min(o => o.Salary),
|
|
||||||
// MaxSalary = g.Max(o => o.Salary)
|
|
||||||
// }).ToShardingListAsync();
|
|
||||||
// Assert.Equal(2, group.Count);
|
|
||||||
// Assert.Equal(2, group[0].Count);
|
|
||||||
// Assert.Equal(2260000, group[0].TotalSalary);
|
|
||||||
// Assert.Equal(1130000, group[0].AvgSalary);
|
|
||||||
// Assert.Equal(11300, group[0].AvgSalaryDecimal);
|
|
||||||
// Assert.Equal(1120000, group[0].MinSalary);
|
|
||||||
// Assert.Equal(1140000, group[0].MaxSalary);
|
|
||||||
// }
|
|
||||||
// [Fact]
|
|
||||||
// public async Task Group_API_Test()
|
|
||||||
// {
|
|
||||||
// var ids = new[] {"200", "300"};
|
|
||||||
// var dateOfMonths = new[] {202111, 202110};
|
|
||||||
// var group = await _virtualDbContext.Set<SysUserSalary>()
|
|
||||||
// .Where(o => ids.Contains(o.UserId) && dateOfMonths.Contains(o.DateOfMonth))
|
|
||||||
// .ShardingGroupByAsync(g => new {UId = g.UserId}, g => new
|
|
||||||
// {
|
|
||||||
//
|
|
||||||
// GroupUserId = g.Key.UId,
|
|
||||||
// Count = g.Count(),
|
|
||||||
// TotalSalary = g.Sum(o => o.Salary),
|
|
||||||
// AvgSalary = g.Average(o => o.Salary),
|
|
||||||
// AvgSalaryDecimal = g.Average(o => o.SalaryDecimal),
|
|
||||||
// MinSalary = g.Min(o => o.Salary),
|
|
||||||
// MaxSalary = g.Max(o => o.Salary)
|
|
||||||
// });
|
|
||||||
// Assert.Equal(2, group.Count);
|
|
||||||
// Assert.Equal(2, group[0].Count);
|
|
||||||
// Assert.Equal(2260000, group[0].TotalSalary);
|
|
||||||
// Assert.Equal(1130000, group[0].AvgSalary);
|
|
||||||
// Assert.Equal(11300, group[0].AvgSalaryDecimal);
|
|
||||||
// Assert.Equal(1120000, group[0].MinSalary);
|
|
||||||
// Assert.Equal(1140000, group[0].MaxSalary);
|
|
||||||
// }
|
|
||||||
// // [Fact]
|
|
||||||
// // public async Task UpdateColumn()
|
|
||||||
// // {
|
|
||||||
// // var item = await _virtualDbContext.Set<SysUserMod>().Where(o=>o.Id=="147").ShardingFirstOrDefaultAsync();
|
|
||||||
// // var oldName = item.Name;
|
|
||||||
// // var oldAge = item.Age;
|
|
||||||
// // var newName = $"test_{new Random().Next(0, 99999)}";
|
|
||||||
// // var newAge = new Random().Next(0, 99999);
|
|
||||||
// // item.Name = newName;
|
|
||||||
// // item.Age = newAge;
|
|
||||||
// // _virtualDbContext.UpdateColumns(item,o=>new {o.Name});
|
|
||||||
// // await _virtualDbContext.SaveChangesAsync();
|
|
||||||
// //
|
|
||||||
// // var newItem = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "147").ShardingFirstOrDefaultAsync();
|
|
||||||
// // Assert.Equal(newName, newItem.Name);
|
|
||||||
// // Assert.NotEqual(oldName, newItem.Name);
|
|
||||||
// // Assert.NotEqual(newAge, newItem.Age);
|
|
||||||
// // Assert.Equal(oldAge, newItem.Age);
|
|
||||||
// // }
|
|
||||||
// // [Fact]
|
|
||||||
// // public async Task UpdateIgnoreColumn()
|
|
||||||
// // {
|
|
||||||
// // var item = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "153").ShardingFirstOrDefaultAsync();
|
|
||||||
// // var oldName = item.Name;
|
|
||||||
// // var oldAge = item.Age;
|
|
||||||
// // var newName = $"test_{new Random().Next(0, 99999)}";
|
|
||||||
// // var newAge = new Random().Next(0, 99999);
|
|
||||||
// // item.Name = newName;
|
|
||||||
// // item.Age = newAge;
|
|
||||||
// // _virtualDbContext.UpdateWithOutIgnoreColumns(item, o => new { o.Name });
|
|
||||||
// // await _virtualDbContext.SaveChangesAsync();
|
|
||||||
// //
|
|
||||||
// // var newItem = await _virtualDbContext.Set<SysUserMod>().Where(o => o.Id == "153").ShardingFirstOrDefaultAsync();
|
|
||||||
// // Assert.NotEqual(newName, newItem.Name);
|
|
||||||
// // Assert.Equal(oldName, newItem.Name);
|
|
||||||
// // Assert.Equal(newAge, newItem.Age);
|
|
||||||
// // Assert.NotEqual(oldAge, newItem.Age);
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// }
|
|
|
@ -1,19 +0,0 @@
|
||||||
using ShardingCore.VirtualRoutes.Mods;
|
|
||||||
using ShardingCoreTestSqlServer3x.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x.Shardings
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Thursday, 14 January 2021 15:39:27
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserModVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUserMod>
|
|
||||||
{
|
|
||||||
public SysUserModVirtualTableRoute() : base(2,3)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using ShardingCore.Core.VirtualRoutes;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
|
||||||
using ShardingCoreTestSqlServer3x.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x.Shardings
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Monday, 01 February 2021 15:54:55
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class SysUserSalaryVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using ShardingCore;
|
|
||||||
using ShardingCoreTestSqlServer3x.Domain.Entities;
|
|
||||||
|
|
||||||
namespace ShardingCoreTestSqlServer3x
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Friday, 15 January 2021 15:37:46
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
// // 自定义 host 构建
|
|
||||||
public void ConfigureHost(IHostBuilder hostBuilder)
|
|
||||||
{
|
|
||||||
hostBuilder
|
|
||||||
.ConfigureAppConfiguration(builder =>
|
|
||||||
{
|
|
||||||
builder.AddJsonFile("Configs/DbConfig.json");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 支持的形式:
|
|
||||||
// ConfigureServices(IServiceCollection services)
|
|
||||||
// ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
|
||||||
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
|
|
||||||
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
|
||||||
{
|
|
||||||
// services.AddShardingSqlServer(o =>
|
|
||||||
// {
|
|
||||||
// o.EnsureCreatedWithOutShardingTable = true;
|
|
||||||
// o.CreateShardingTableOnStart = true;
|
|
||||||
// o.UseShardingDbContext<DefaultDbContext>(dbConfig =>
|
|
||||||
// {
|
|
||||||
// dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
|
||||||
// dbConfig.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
|
||||||
// });
|
|
||||||
// //o.AddDataSourceVirtualRoute<>();
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
// services.AddDbContext<DefaultDbContext>(o =>
|
|
||||||
// o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"])
|
|
||||||
// .UseShardingSqlServerUpdateSqlGenerator());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法
|
|
||||||
public void Configure(IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
var shardingBootstrapper = serviceProvider.GetService<IShardingBootstrapper>();
|
|
||||||
shardingBootstrapper.Start();
|
|
||||||
// 有一些测试数据要初始化可以放在这里
|
|
||||||
InitData(serviceProvider).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 添加种子数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serviceProvider"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private async Task InitData(IServiceProvider serviceProvider)
|
|
||||||
{
|
|
||||||
using (var scope = serviceProvider.CreateScope())
|
|
||||||
{
|
|
||||||
var virtualDbContext = scope.ServiceProvider.GetService<DefaultDbContext>();
|
|
||||||
if (!await virtualDbContext.Set<SysUserMod>().AnyAsync(o => true))
|
|
||||||
{
|
|
||||||
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}",
|
|
||||||
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,
|
|
||||||
SalaryLong = 700000+id*100*i,
|
|
||||||
SalaryDecimal = (700000+id*100*i)/100m,
|
|
||||||
SalaryDouble = (700000+id*100*i)/100d,
|
|
||||||
SalaryFloat = (700000+id*100*i)/100f
|
|
||||||
});
|
|
||||||
tempTime=tempTime.AddMonths(1);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await virtualDbContext.AddRangeAsync(userMods);
|
|
||||||
await virtualDbContext.AddRangeAsync(userSalaries);
|
|
||||||
|
|
||||||
await virtualDbContext.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue