添加测试3x的sqlserver
This commit is contained in:
parent
3f8edb65e0
commit
b731c41f02
|
@ -39,7 +39,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.Test50.MySql",
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.AutoByDate.SqlServer", "samples\Samples.AutoByDate.SqlServer\Samples.AutoByDate.SqlServer.csproj", "{C34FCF48-1A98-4268-BFEE-6C9BFC7FD539}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.AutoByDate.SqlServer", "samples\Samples.AutoByDate.SqlServer\Samples.AutoByDate.SqlServer.csproj", "{C34FCF48-1A98-4268-BFEE-6C9BFC7FD539}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.MySql", "samples\Sample.MySql\Sample.MySql.csproj", "{90675788-D5C3-415A-9C18-FF159A75B4D5}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.MySql", "samples\Sample.MySql\Sample.MySql.csproj", "{90675788-D5C3-415A-9C18-FF159A75B4D5}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.SqlServer3x", "samples\Sample.SqlServer3x\Sample.SqlServer3x.csproj", "{447D5357-F095-45DE-9DA5-2D9997237366}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShardingCoreTestSqlServer3x", "test\ShardingCoreTestSqlServer3x\ShardingCoreTestSqlServer3x.csproj", "{1CE858B8-56D8-4009-BF46-EE0F79F259D1}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -103,6 +107,14 @@ Global
|
||||||
{90675788-D5C3-415A-9C18-FF159A75B4D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{90675788-D5C3-415A-9C18-FF159A75B4D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{90675788-D5C3-415A-9C18-FF159A75B4D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{90675788-D5C3-415A-9C18-FF159A75B4D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{90675788-D5C3-415A-9C18-FF159A75B4D5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{90675788-D5C3-415A-9C18-FF159A75B4D5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{447D5357-F095-45DE-9DA5-2D9997237366}.Debug|Any CPU.ActiveCfg = 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.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
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -122,6 +134,8 @@ Global
|
||||||
{C8FAB96F-F13E-4094-883C-2D38D39EE4A3} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
{C8FAB96F-F13E-4094-883C-2D38D39EE4A3} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
||||||
{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}
|
||||||
|
{1CE858B8-56D8-4009-BF46-EE0F79F259D1} = {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}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class WeatherForecastController : ControllerBase
|
||||||
|
{
|
||||||
|
private static readonly string[] Summaries = new[]
|
||||||
|
{
|
||||||
|
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly ILogger<WeatherForecastController> _logger;
|
||||||
|
|
||||||
|
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public IEnumerable<WeatherForecast> Get()
|
||||||
|
{
|
||||||
|
var rng = new Random();
|
||||||
|
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||||
|
{
|
||||||
|
Date = DateTime.Now.AddDays(index),
|
||||||
|
TemperatureC = rng.Next(-20, 55),
|
||||||
|
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||||
|
})
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sample.SqlServer3x.Domain.Maps;
|
||||||
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
using ShardingCore.Core;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x.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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
using Sample.SqlServer3x.Domain.Entities;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x.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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
CreateHostBuilder(args).Build().Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||||
|
Host.CreateDefaultBuilder(args)
|
||||||
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
|
{
|
||||||
|
webBuilder.UseStartup<Startup>();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:55565",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "weatherforecast",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Sample.SqlServer3x": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "weatherforecast",
|
||||||
|
"applicationUrl": "http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src3x\ShardingCore.SqlServer.3x\ShardingCore.SqlServer.3x.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Sample.SqlServer3x.Domain.Entities;
|
||||||
|
using ShardingCore.VirtualRoutes.Mods;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x.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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Sample.SqlServer3x.Domain.Entities;
|
||||||
|
using Sample.SqlServer3x.Shardings;
|
||||||
|
using ShardingCore;
|
||||||
|
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||||
|
using ShardingCore.Extensions;
|
||||||
|
using ShardingCore.SqlServer;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public Startup(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to add services to the container.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddControllers();
|
||||||
|
services.AddShardingSqlServer(o =>
|
||||||
|
{
|
||||||
|
o.EnsureCreatedWithOutShardingTable = true;
|
||||||
|
o.CreateShardingTableOnStart = true;
|
||||||
|
o.AddShardingDbContextWithShardingTable<DefaultDbContext>("conn1", "Data Source=localhost;Initial Catalog=ShardingCoreDB3x;Integrated Security=True", dbConfig =>
|
||||||
|
{
|
||||||
|
dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||||
|
});
|
||||||
|
//o.AddDataSourceVirtualRoute<>();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
|
{
|
||||||
|
if (env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseDeveloperExceptionPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
var shardingBootstrapper = app.ApplicationServices.GetService<IShardingBootstrapper>();
|
||||||
|
shardingBootstrapper.Start();
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
|
||||||
|
InitData(app).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ìí¼ÓÖÖ×ÓÊý¾Ý
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="serviceProvider"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task InitData(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
var serviceProvider = app.ApplicationServices;
|
||||||
|
using (var scope = serviceProvider.CreateScope())
|
||||||
|
{
|
||||||
|
var virtualDbContext = scope.ServiceProvider.GetService<IVirtualDbContext>();
|
||||||
|
if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(o => true))
|
||||||
|
{
|
||||||
|
var ids = Enumerable.Range(1, 1000);
|
||||||
|
var userMods = new List<SysUserMod>();
|
||||||
|
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)
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
await virtualDbContext.InsertRangeAsync(userMods);
|
||||||
|
|
||||||
|
await virtualDbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Sample.SqlServer3x
|
||||||
|
{
|
||||||
|
public class WeatherForecast
|
||||||
|
{
|
||||||
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureC { get; set; }
|
||||||
|
|
||||||
|
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||||
|
|
||||||
|
public string Summary { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft": "Warning",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
|
using ShardingCore.Test50.Domain.Maps;
|
||||||
|
|
||||||
|
namespace ShardingCore.Test50
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* @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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,19 @@ 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.AddShardingSqlServer(o =>
|
||||||
|
{
|
||||||
|
o.EnsureCreatedWithOutShardingTable = true;
|
||||||
|
o.CreateShardingTableOnStart = true;
|
||||||
|
o.AddShardingDbContextWithShardingTable<DefaultDbContext>("conn1", hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"], dbConfig =>
|
||||||
|
{
|
||||||
|
dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||||
|
dbConfig.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||||
|
});
|
||||||
|
//o.AddDataSourceVirtualRoute<>();
|
||||||
|
|
||||||
|
});
|
||||||
//services.AddShardingSqlServer(o =>
|
//services.AddShardingSqlServer(o =>
|
||||||
//{
|
//{
|
||||||
// o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
|
// o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"SqlServer": {
|
||||||
|
"ConnectionString": "Data Source=localhost;Initial Catalog=ShardingCoreDB3x;Integrated Security=True"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
|
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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
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; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
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; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<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>
|
|
@ -0,0 +1,352 @@
|
||||||
|
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 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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
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 ShardingCoreTestSqlServer3x.Domain.Entities;
|
||||||
|
using ShardingCoreTestSqlServer3x.Shardings;
|
||||||
|
|
||||||
|
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.AddShardingDbContextWithShardingTable<DefaultDbContext>("conn1", hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"], dbConfig =>
|
||||||
|
{
|
||||||
|
dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||||
|
dbConfig.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||||
|
});
|
||||||
|
//o.AddDataSourceVirtualRoute<>();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 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<IVirtualDbContext>();
|
||||||
|
if (!await virtualDbContext.Set<SysUserMod>().ShardingAnyAsync(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.InsertRangeAsync(userMods);
|
||||||
|
await virtualDbContext.InsertRangeAsync(userSalaries);
|
||||||
|
|
||||||
|
await virtualDbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue