修复分库join的bug,添加对sharding-table,sharding-data-source的demo
This commit is contained in:
parent
4f0828d47f
commit
579c5cc6db
|
@ -47,6 +47,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.5x", "src5x\Sh
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Migrations", "samples\Sample.Migrations\Sample.Migrations.csproj", "{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Migrations", "samples\Sample.Migrations\Sample.Migrations.csproj", "{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.SqlServerShardingTable", "samples\Sample.SqlServerShardingTable\Sample.SqlServerShardingTable.csproj", "{88FA5615-1BAA-4021-87EF-9D4A60257FE4}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -117,6 +119,10 @@ Global
|
||||||
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Release|Any CPU.Build.0 = Release|Any CPU
|
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{88FA5615-1BAA-4021-87EF-9D4A60257FE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{88FA5615-1BAA-4021-87EF-9D4A60257FE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{88FA5615-1BAA-4021-87EF-9D4A60257FE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{88FA5615-1BAA-4021-87EF-9D4A60257FE4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -138,6 +144,7 @@ Global
|
||||||
{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
{0193E3CF-F2FD-449A-B2D5-7F68E551FDBF} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||||
{68A9F118-EF0A-4D03-8845-77D084561A28} = {EB1C9149-78C9-4D99-BE3F-B80FE2015E96}
|
{68A9F118-EF0A-4D03-8845-77D084561A28} = {EB1C9149-78C9-4D99-BE3F-B80FE2015E96}
|
||||||
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
{648DCBBE-BE8F-4EAC-8367-FE7BC558DA8C} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||||
|
{88FA5615-1BAA-4021-87EF-9D4A60257FE4} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||||
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.3.1.26
|
set EFCORE2=2.3.1.27
|
||||||
set EFCORE3=3.3.1.26
|
set EFCORE3=3.3.1.27
|
||||||
set EFCORE5=5.3.1.26
|
set EFCORE5=5.3.1.27
|
||||||
|
|
||||||
::删除所有bin与obj下的文件
|
::删除所有bin与obj下的文件
|
||||||
@echo off
|
@echo off
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sample.SqlServerShardingDataSource.Entities;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingDataSource.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]/[action]")]
|
||||||
|
public class TestController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly MyDbContext _myDbContext;
|
||||||
|
|
||||||
|
public TestController(MyDbContext myDbContext)
|
||||||
|
{
|
||||||
|
_myDbContext = myDbContext;
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Query()
|
||||||
|
{
|
||||||
|
var sysUser =await _myDbContext.Set<SysUser>().Where(o=>o.Id=="1").FirstOrDefaultAsync();
|
||||||
|
var dateTime = new DateTime(2021,3,5);
|
||||||
|
var order = await _myDbContext.Set<Order>().Where(o=>o.CreationTime>= dateTime).OrderBy(o=>o.CreationTime).FirstOrDefaultAsync();
|
||||||
|
var orderIdOne = await _myDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == "3");
|
||||||
|
|
||||||
|
|
||||||
|
var sysUsers = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1" || o.Id=="6").ToListAsync();
|
||||||
|
|
||||||
|
return Ok(new object[]
|
||||||
|
{
|
||||||
|
sysUser,
|
||||||
|
order,
|
||||||
|
orderIdOne,
|
||||||
|
sysUsers
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> QueryJoin()
|
||||||
|
{
|
||||||
|
var begin = new DateTime(2021, 3, 2);
|
||||||
|
var end = new DateTime(2021, 4, 3);
|
||||||
|
var sql1 = from user in _myDbContext.Set<SysUser>().Where(o => o.Id == "1" || o.Id == "6")
|
||||||
|
join order in _myDbContext.Set<Order>().Where(o=>o.CreationTime>=begin&&o.CreationTime<=end)
|
||||||
|
on user.Id equals order.Payer
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
user.Id,
|
||||||
|
user.Name,
|
||||||
|
user.Area,
|
||||||
|
OrderId = order.Id,
|
||||||
|
order.Payer,
|
||||||
|
order.CreationTime
|
||||||
|
};
|
||||||
|
return Ok(await sql1.ToListAsync());
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> QueryJoin2()
|
||||||
|
{
|
||||||
|
var begin = new DateTime(2021, 3, 2);
|
||||||
|
var end = new DateTime(2021, 4, 3);
|
||||||
|
var sql1 = from user in _myDbContext.Set<SysUser>().Where(o => (o.Id == "1" || o.Id == "6")&&o.Area=="A")
|
||||||
|
join order in _myDbContext.Set<Order>().Where(o => o.CreationTime >= begin && o.CreationTime <= end)
|
||||||
|
on user.Id equals order.Payer
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
user.Id,
|
||||||
|
user.Name,
|
||||||
|
user.Area,
|
||||||
|
OrderId = order.Id,
|
||||||
|
order.Payer,
|
||||||
|
order.CreationTime
|
||||||
|
};
|
||||||
|
return Ok(await sql1.ToListAsync());
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Update()
|
||||||
|
{
|
||||||
|
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1").FirstOrDefaultAsync();
|
||||||
|
sysUser.Name = "new name";
|
||||||
|
var i=await _myDbContext.SaveChangesAsync();
|
||||||
|
return Ok(i);
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Update1()
|
||||||
|
{
|
||||||
|
var sysUser = await _myDbContext.Set<SysUser>().AsNoTracking().Where(o => o.Id == "1").FirstOrDefaultAsync();
|
||||||
|
sysUser.Name = "new name";
|
||||||
|
_myDbContext.Update(sysUser);
|
||||||
|
var i = await _myDbContext.SaveChangesAsync();
|
||||||
|
return Ok(i);
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Delete()
|
||||||
|
{
|
||||||
|
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "9").FirstOrDefaultAsync();
|
||||||
|
_myDbContext.Remove(sysUser);
|
||||||
|
var i = await _myDbContext.SaveChangesAsync();
|
||||||
|
return Ok(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,10 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Sample.SqlServerShardingDataSource.DbContexts;
|
|
||||||
using Sample.SqlServerShardingDataSource.Domain.Entities;
|
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource.Controllers
|
namespace Sample.SqlServerShardingDataSource.Controllers
|
||||||
{
|
{
|
||||||
|
@ -20,40 +18,15 @@ namespace Sample.SqlServerShardingDataSource.Controllers
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly ILogger<WeatherForecastController> _logger;
|
private readonly ILogger<WeatherForecastController> _logger;
|
||||||
private readonly DefaultShardingDbContext _defaultShardingDbContext;
|
|
||||||
|
|
||||||
public WeatherForecastController(ILogger<WeatherForecastController> logger, DefaultShardingDbContext defaultShardingDbContext)
|
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_defaultShardingDbContext = defaultShardingDbContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IEnumerable<WeatherForecast>> Get()
|
public async Task<IEnumerable<WeatherForecast>> Get()
|
||||||
{
|
{
|
||||||
var resultx112331 = await _defaultShardingDbContext.Set<SysUserMod>().CountAsync();
|
|
||||||
var resultx11233411 = _defaultShardingDbContext.Set<SysUserMod>().Count();
|
|
||||||
var resultx11231 = await _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Age == 198198).Select(o => o.Id).ContainsAsync("1981");
|
|
||||||
var resultx1121 = await _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").SumAsync(o => o.Age);
|
|
||||||
var resultx111 = await _defaultShardingDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "198");
|
|
||||||
var resultx2 = await _defaultShardingDbContext.Set<SysUserMod>().CountAsync(o => o.Age <= 10);
|
|
||||||
var resultx = await _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").FirstOrDefaultAsync();
|
|
||||||
var resultx33 = await _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Select(o => o.Id).FirstOrDefaultAsync();
|
|
||||||
var resulxxt = await _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").ToListAsync();
|
|
||||||
var result = await _defaultShardingDbContext.Set<SysUserMod>().ToListAsync();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var sresultx11231 = _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Age == 198198).Select(o => o.Id).Contains("1981");
|
|
||||||
var sresultx1121 = _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Sum(o => o.Age);
|
|
||||||
var sresultx111 = _defaultShardingDbContext.Set<SysUserMod>().FirstOrDefault(o => o.Id == "198");
|
|
||||||
var sresultx2 = _defaultShardingDbContext.Set<SysUserMod>().Count(o => o.Age <= 10);
|
|
||||||
var sresultx = _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").FirstOrDefault();
|
|
||||||
var sresultx33 = _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Select(o => o.Id).FirstOrDefault();
|
|
||||||
var sresultxc = _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").Select(o => o.Id).ToList();
|
|
||||||
var sresultxasdc = _defaultShardingDbContext.Set<SysUserMod>().Where(o => o.Id == "198").ToList();
|
|
||||||
var sresult = _defaultShardingDbContext.Set<SysUserMod>().ToList();
|
|
||||||
var rng = new Random();
|
var rng = new Random();
|
||||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Sample.SqlServerShardingDataSource.DbContexts;
|
|
||||||
using Sample.SqlServerShardingDataSource.Domain.Entities;
|
|
||||||
using ShardingCore;
|
|
||||||
using ShardingCore.Bootstrapers;
|
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Tuesday, 26 January 2021 12:29:04
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
public static class DIExtension
|
|
||||||
{
|
|
||||||
public static IApplicationBuilder UseShardingCore(this IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
var shardingBootstrapper = app.ApplicationServices.GetRequiredService<IShardingBootstrapper>();
|
|
||||||
shardingBootstrapper.Start();
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DbSeed(this IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
using (var scope = app.ApplicationServices.CreateScope())
|
|
||||||
{
|
|
||||||
var virtualDbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
|
||||||
if (!virtualDbContext.Set<SysUserMod>().Any())
|
|
||||||
{
|
|
||||||
var ids = Enumerable.Range(1, 1000);
|
|
||||||
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)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
virtualDbContext.AddRange(userMods);
|
|
||||||
|
|
||||||
virtualDbContext.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Sample.SqlServerShardingDataSource.Domain.Maps;
|
|
||||||
using ShardingCore.Sharding;
|
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource.DbContexts
|
|
||||||
{
|
|
||||||
public class DefaultShardingDbContext:AbstractShardingDbContext
|
|
||||||
{
|
|
||||||
public DefaultShardingDbContext(DbContextOptions options) : base(options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
|
||||||
{
|
|
||||||
base.OnModelCreating(modelBuilder);
|
|
||||||
modelBuilder.ApplyConfiguration(new SysUserModMap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
using ShardingCore.Core;
|
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource.Domain.Entities
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* @Author: xjm
|
|
||||||
* @Description:
|
|
||||||
* @Date: Tuesday, 26 January 2021 12:25:39
|
|
||||||
* @Email: 326308290@qq.com
|
|
||||||
*/
|
|
||||||
/// <summary>
|
|
||||||
/// 用户表
|
|
||||||
/// </summary>
|
|
||||||
public class SysUserMod : IShardingDataSource
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用户Id用于分库
|
|
||||||
/// </summary>
|
|
||||||
[ShardingDataSourceKey]
|
|
||||||
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 Sample.SqlServerShardingDataSource.Domain.Entities;
|
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource.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,42 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingDataSource.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// order table
|
||||||
|
/// </summary>
|
||||||
|
public class Order
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// order Id
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// payer id
|
||||||
|
/// </summary>
|
||||||
|
public string Payer { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// pay money cent
|
||||||
|
/// </summary>
|
||||||
|
public long Money { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// area
|
||||||
|
/// </summary>
|
||||||
|
public string Area { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// order status
|
||||||
|
/// </summary>
|
||||||
|
public OrderStatusEnum OrderStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// CreationTime
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreationTime { get; set; }
|
||||||
|
}
|
||||||
|
public enum OrderStatusEnum
|
||||||
|
{
|
||||||
|
NoPay=1,
|
||||||
|
Paying=2,
|
||||||
|
Payed=3,
|
||||||
|
PayFail=4
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
namespace Sample.SqlServerShardingDataSource.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// user table
|
||||||
|
/// </summary>
|
||||||
|
public class SysUser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// user id
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// user name
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// area
|
||||||
|
/// </summary>
|
||||||
|
public string Area { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sample.SqlServerShardingDataSource.Entities;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||||
|
using ShardingCore.Sharding;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingDataSource
|
||||||
|
{
|
||||||
|
public class MyDbContext:AbstractShardingDbContext,IShardingTableDbContext
|
||||||
|
{
|
||||||
|
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
base.OnModelCreating(modelBuilder);
|
||||||
|
modelBuilder.Entity<Order>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(o => o.Id);
|
||||||
|
entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Payer).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o => o.Area).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o => o.OrderStatus).HasConversion<int>();
|
||||||
|
entity.ToTable(nameof(Order));
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<SysUser>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(o => o.Id);
|
||||||
|
entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Name).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Area).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.ToTable(nameof(SysUser));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRouteTail RouteTail { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,13 @@
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using Sample.SqlServerShardingDataSource.VirtualRoutes;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Sample.SqlServerShardingDataSource.DbContexts;
|
|
||||||
using Sample.SqlServerShardingDataSource.Shardings;
|
|
||||||
using ShardingCore;
|
using ShardingCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource
|
namespace Sample.SqlServerShardingDataSource
|
||||||
{
|
{
|
||||||
|
@ -35,28 +30,39 @@ namespace Sample.SqlServerShardingDataSource
|
||||||
|
|
||||||
services.AddControllers();
|
services.AddControllers();
|
||||||
|
|
||||||
|
services.AddShardingDbContext<MyDbContext>((conStr, builder) =>
|
||||||
services.AddShardingDbContext<DefaultShardingDbContext>(
|
|
||||||
(conn, o) =>
|
|
||||||
o.UseSqlServer(conn).UseLoggerFactory(efLogger)
|
|
||||||
).Begin(o =>
|
|
||||||
{
|
{
|
||||||
o.CreateShardingTableOnStart = true;
|
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
|
||||||
o.EnsureCreatedWithOutShardingTable = true;
|
}).Begin(op =>
|
||||||
})
|
{
|
||||||
.AddShardingTransaction((connection, builder) =>
|
op.AutoTrackEntity = true;
|
||||||
builder.UseSqlServer(connection).UseLoggerFactory(efLogger))
|
//如果您使用code-first建议选择false
|
||||||
.AddDefaultDataSource("ds0","Data Source=localhost;Initial Catalog=ShardingCoreDBxx0;Integrated Security=True;")
|
op.CreateShardingTableOnStart = true;
|
||||||
|
//如果您使用code-first建议修改为fsle
|
||||||
|
op.EnsureCreatedWithOutShardingTable = true;
|
||||||
|
}).AddShardingTransaction((connection, builder) =>
|
||||||
|
{
|
||||||
|
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
|
||||||
|
}).AddDefaultDataSource("A",
|
||||||
|
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceDBA;Integrated Security=True;")
|
||||||
.AddShardingDataSource(sp =>
|
.AddShardingDataSource(sp =>
|
||||||
{
|
{
|
||||||
return new Dictionary<string, string>()
|
return new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{"ds1", "Data Source=localhost;Initial Catalog=ShardingCoreDBxx1;Integrated Security=True;"},
|
|
||||||
{"ds2", "Data Source=localhost;Initial Catalog=ShardingCoreDBxx2;Integrated Security=True;"},
|
|
||||||
};
|
|
||||||
}).AddShardingDataSourceRoute(o =>
|
|
||||||
{
|
{
|
||||||
o.AddShardingDatabaseRoute<SysUserModVirtualDataSourceRoute>();
|
"B",
|
||||||
|
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceDBB;Integrated Security=True;"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"C",
|
||||||
|
"Data Source=localhost;Initial Catalog=EFCoreShardingDataSourceDBC;Integrated Security=True;"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.AddShardingDataSourceRoute(op =>
|
||||||
|
{
|
||||||
|
op.AddShardingDatabaseRoute<SysUserVirtualDataSourceRoute>();
|
||||||
|
op.AddShardingDatabaseRoute<OrderVirtualDataSourceRoute>();
|
||||||
}).End();
|
}).End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +83,7 @@ namespace Sample.SqlServerShardingDataSource
|
||||||
{
|
{
|
||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
});
|
});
|
||||||
app.DbSeed();
|
app.InitSeed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Sample.SqlServerShardingDataSource.Entities;
|
||||||
|
using ShardingCore.Bootstrapers;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingDataSource
|
||||||
|
{
|
||||||
|
public static class StartupExtension
|
||||||
|
{
|
||||||
|
public static void UseShardingCore(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.ApplicationServices.GetRequiredService<IShardingBootstrapper>().Start();
|
||||||
|
}
|
||||||
|
public static void InitSeed(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
using (var serviceScope = app.ApplicationServices.CreateScope())
|
||||||
|
{
|
||||||
|
var myDbContext = serviceScope.ServiceProvider.GetRequiredService<MyDbContext>();
|
||||||
|
if (!myDbContext.Set<SysUser>().Any())
|
||||||
|
{
|
||||||
|
string[] areas = new string[] {"A","B","C" };
|
||||||
|
List<SysUser> users = new List<SysUser>(10);
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
var uer=new SysUser()
|
||||||
|
{
|
||||||
|
Id = i.ToString(),
|
||||||
|
Name = $"MyName{i}",
|
||||||
|
Area = areas[i % 3]
|
||||||
|
};
|
||||||
|
users.Add(uer);
|
||||||
|
}
|
||||||
|
List<Order> orders = new List<Order>(300);
|
||||||
|
var begin = new DateTime(2021, 1, 1, 3, 3, 3);
|
||||||
|
for (int i = 0; i < 300; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
var order = new Order()
|
||||||
|
{
|
||||||
|
Id = i.ToString(),
|
||||||
|
Payer = $"{i % 10}",
|
||||||
|
Money = 100+new Random().Next(100,3000),
|
||||||
|
OrderStatus = (OrderStatusEnum)(i % 4 + 1),
|
||||||
|
Area = areas[i % 3],
|
||||||
|
CreationTime = begin.AddDays(i)
|
||||||
|
};
|
||||||
|
orders.Add(order);
|
||||||
|
}
|
||||||
|
myDbContext.AddRange(users);
|
||||||
|
myDbContext.AddRange(orders);
|
||||||
|
myDbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using Sample.SqlServerShardingDataSource.Entities;
|
||||||
|
using ShardingCore.Core.EntityMetadatas;
|
||||||
|
using ShardingCore.Core.VirtualRoutes;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingDataSource.VirtualRoutes
|
||||||
|
{
|
||||||
|
public class OrderVirtualDataSourceRoute : AbstractShardingOperatorVirtualDataSourceRoute<Order, string>
|
||||||
|
{
|
||||||
|
private readonly List<string> _dataSources = new List<string>()
|
||||||
|
{
|
||||||
|
"A", "B", "C"
|
||||||
|
};
|
||||||
|
protected override string ConvertToShardingKey(object shardingKey)
|
||||||
|
{
|
||||||
|
return shardingKey?.ToString() ?? string.Empty;
|
||||||
|
}
|
||||||
|
//我们设置区域就是数据库
|
||||||
|
public override string ShardingKeyToDataSourceName(object shardingKey)
|
||||||
|
{
|
||||||
|
return ConvertToShardingKey(shardingKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<string> GetAllDataSourceNames()
|
||||||
|
{
|
||||||
|
return _dataSources;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool AddDataSourceName(string dataSourceName)
|
||||||
|
{
|
||||||
|
if (_dataSources.Any(o => o == dataSourceName))
|
||||||
|
return false;
|
||||||
|
_dataSources.Add(dataSourceName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
|
{
|
||||||
|
|
||||||
|
var t = ShardingKeyToDataSourceName(shardingKey);
|
||||||
|
switch (shardingOperator)
|
||||||
|
{
|
||||||
|
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return tail => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Configure(EntityMetadataDataSourceBuilder<Order> builder)
|
||||||
|
{
|
||||||
|
builder.ShardingProperty(o => o.Area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,45 +2,40 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Threading.Tasks;
|
using Sample.SqlServerShardingDataSource.Entities;
|
||||||
using Sample.SqlServerShardingDataSource.Domain.Entities;
|
|
||||||
using ShardingCore.Core.EntityMetadatas;
|
using ShardingCore.Core.EntityMetadatas;
|
||||||
using ShardingCore.Core.VirtualRoutes;
|
using ShardingCore.Core.VirtualRoutes;
|
||||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions;
|
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions;
|
||||||
using ShardingCore.Helpers;
|
|
||||||
|
|
||||||
namespace Sample.SqlServerShardingDataSource.Shardings
|
namespace Sample.SqlServerShardingDataSource.VirtualRoutes
|
||||||
{
|
{
|
||||||
public class SysUserModVirtualDataSourceRoute:AbstractShardingOperatorVirtualDataSourceRoute<SysUserMod,string>
|
public class SysUserVirtualDataSourceRoute : AbstractShardingOperatorVirtualDataSourceRoute<SysUser, string>
|
||||||
{
|
{
|
||||||
protected readonly int Mod=3;
|
private readonly List<string> _dataSources = new List<string>()
|
||||||
protected readonly int TailLength=1;
|
{
|
||||||
protected readonly char PaddingChar='0';
|
"A", "B", "C"
|
||||||
|
};
|
||||||
protected override string ConvertToShardingKey(object shardingKey)
|
protected override string ConvertToShardingKey(object shardingKey)
|
||||||
{
|
{
|
||||||
return shardingKey.ToString();
|
return shardingKey?.ToString() ?? string.Empty;
|
||||||
}
|
}
|
||||||
|
//我们设置区域就是数据库
|
||||||
public override string ShardingKeyToDataSourceName(object shardingKey)
|
public override string ShardingKeyToDataSourceName(object shardingKey)
|
||||||
{
|
{
|
||||||
var shardingKeyStr = ConvertToShardingKey(shardingKey);
|
return ConvertToShardingKey(shardingKey);
|
||||||
return "ds"+Math.Abs(ShardingCoreHelper.GetStringHashCode(shardingKeyStr) % Mod).ToString().PadLeft(TailLength, PaddingChar); ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override List<string> GetAllDataSourceNames()
|
public override List<string> GetAllDataSourceNames()
|
||||||
{
|
{
|
||||||
return new List<string>()
|
return _dataSources;
|
||||||
{
|
|
||||||
"ds0",
|
|
||||||
"ds1",
|
|
||||||
"ds2"
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool AddDataSourceName(string dataSourceName)
|
public override bool AddDataSourceName(string dataSourceName)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (_dataSources.Any(o => o == dataSourceName))
|
||||||
|
return false;
|
||||||
|
_dataSources.Add(dataSourceName);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||||
|
@ -57,5 +52,9 @@ namespace Sample.SqlServerShardingDataSource.Shardings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Configure(EntityMetadataDataSourceBuilder<SysUser> builder)
|
||||||
|
{
|
||||||
|
builder.ShardingProperty(o => o.Area);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sample.SqlServerShardingTable.Entities;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]/[action]")]
|
||||||
|
public class TestController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly MyDbContext _myDbContext;
|
||||||
|
|
||||||
|
public TestController(MyDbContext myDbContext)
|
||||||
|
{
|
||||||
|
_myDbContext = myDbContext;
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Query()
|
||||||
|
{
|
||||||
|
var sysUser =await _myDbContext.Set<SysUser>().Where(o=>o.Id=="1").FirstOrDefaultAsync();
|
||||||
|
var dateTime = new DateTime(2021,3,5);
|
||||||
|
var order = await _myDbContext.Set<Order>().Where(o=>o.CreationTime>= dateTime).OrderBy(o=>o.CreationTime).FirstOrDefaultAsync();
|
||||||
|
var orderIdOne = await _myDbContext.Set<Order>().FirstOrDefaultAsync(o => o.Id == "3");
|
||||||
|
|
||||||
|
var sysUsers = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1" || o.Id=="6").ToListAsync();
|
||||||
|
|
||||||
|
return Ok(new object[]
|
||||||
|
{
|
||||||
|
sysUser,
|
||||||
|
order,
|
||||||
|
orderIdOne,
|
||||||
|
sysUsers
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> QueryJoin1()
|
||||||
|
{
|
||||||
|
var sql= from user in _myDbContext.Set<SysUser>().Where(o => o.Id == "1" || o.Id == "6")
|
||||||
|
join setting in _myDbContext.Set<Setting>()
|
||||||
|
on user.SettingCode equals setting.Code
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
user.Id,
|
||||||
|
user.Name,
|
||||||
|
user.Area,
|
||||||
|
user.SettingCode,
|
||||||
|
SettingName=setting.Name,
|
||||||
|
};
|
||||||
|
return Ok(await sql.ToListAsync());
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> QueryJoin2()
|
||||||
|
{
|
||||||
|
var begin = new DateTime(2021, 3, 2);
|
||||||
|
var end = new DateTime(2021, 4, 3);
|
||||||
|
var sql1 = from user in _myDbContext.Set<SysUser>().Where(o => o.Id == "1" || o.Id == "6")
|
||||||
|
join order in _myDbContext.Set<Order>().Where(o=>o.CreationTime>=begin&&o.CreationTime<=end)
|
||||||
|
on user.Id equals order.Payer
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
user.Id,
|
||||||
|
user.Name,
|
||||||
|
user.Area,
|
||||||
|
user.SettingCode,
|
||||||
|
OrderId = order.Id,
|
||||||
|
order.Payer,
|
||||||
|
order.CreationTime
|
||||||
|
};
|
||||||
|
return Ok(await sql1.ToListAsync());
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Update()
|
||||||
|
{
|
||||||
|
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1").FirstOrDefaultAsync();
|
||||||
|
sysUser.Name = "new name";
|
||||||
|
var i=await _myDbContext.SaveChangesAsync();
|
||||||
|
return Ok(i);
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Update1()
|
||||||
|
{
|
||||||
|
var sysUser = await _myDbContext.Set<SysUser>().AsNoTracking().Where(o => o.Id == "1").FirstOrDefaultAsync();
|
||||||
|
sysUser.Name = "new name";
|
||||||
|
_myDbContext.Update(sysUser);
|
||||||
|
var i = await _myDbContext.SaveChangesAsync();
|
||||||
|
return Ok(i);
|
||||||
|
}
|
||||||
|
public async Task<IActionResult> Delete()
|
||||||
|
{
|
||||||
|
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "9").FirstOrDefaultAsync();
|
||||||
|
_myDbContext.Remove(sysUser);
|
||||||
|
var i = await _myDbContext.SaveChangesAsync();
|
||||||
|
return Ok(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.SqlServerShardingTable.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,42 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// order table
|
||||||
|
/// </summary>
|
||||||
|
public class Order
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// order Id
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// payer id
|
||||||
|
/// </summary>
|
||||||
|
public string Payer { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// pay money cent
|
||||||
|
/// </summary>
|
||||||
|
public long Money { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// area
|
||||||
|
/// </summary>
|
||||||
|
public string Area { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// order status
|
||||||
|
/// </summary>
|
||||||
|
public OrderStatusEnum OrderStatus { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// CreationTime
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreationTime { get; set; }
|
||||||
|
}
|
||||||
|
public enum OrderStatusEnum
|
||||||
|
{
|
||||||
|
NoPay=1,
|
||||||
|
Paying=2,
|
||||||
|
Payed=3,
|
||||||
|
PayFail=4
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace Sample.SqlServerShardingTable.Entities
|
||||||
|
{
|
||||||
|
public class Setting
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// code
|
||||||
|
/// </summary>
|
||||||
|
public string Code { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// user type name
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
namespace Sample.SqlServerShardingTable.Entities
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// user table
|
||||||
|
/// </summary>
|
||||||
|
public class SysUser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// user id
|
||||||
|
/// </summary>
|
||||||
|
public string Id { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// user name
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// area
|
||||||
|
/// </summary>
|
||||||
|
public string Area { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// setting code
|
||||||
|
/// </summary>
|
||||||
|
public string SettingCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Sample.SqlServerShardingTable.Entities;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||||
|
using ShardingCore.Sharding;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable
|
||||||
|
{
|
||||||
|
public class MyDbContext:AbstractShardingDbContext,IShardingTableDbContext
|
||||||
|
{
|
||||||
|
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
base.OnModelCreating(modelBuilder);
|
||||||
|
modelBuilder.Entity<Order>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(o => o.Id);
|
||||||
|
entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Payer).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o => o.Area).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o => o.OrderStatus).HasConversion<int>();
|
||||||
|
entity.ToTable(nameof(Order));
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<SysUser>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(o => o.Id);
|
||||||
|
entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Name).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Area).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o => o.SettingCode).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.ToTable(nameof(SysUser));
|
||||||
|
});
|
||||||
|
modelBuilder.Entity<Setting>(entity =>
|
||||||
|
{
|
||||||
|
entity.HasKey(o => o.Code);
|
||||||
|
entity.Property(o => o.Code).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.Property(o=>o.Name).IsRequired().IsUnicode(false).HasMaxLength(50);
|
||||||
|
entity.ToTable(nameof(Setting));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public IRouteTail RouteTail { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -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.SqlServerShardingTable
|
||||||
|
{
|
||||||
|
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,23 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:14596",
|
||||||
|
"sslPort": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"Sample.SqlServerShardingTable": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"dotnetRunMessages": "true",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "weatherforecast",
|
||||||
|
"applicationUrl": "http://localhost:5000",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net5.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.11" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,78 @@
|
||||||
|
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 Microsoft.EntityFrameworkCore;
|
||||||
|
using Sample.SqlServerShardingTable.VirtualRoutes;
|
||||||
|
using ShardingCore;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder =>
|
||||||
|
{
|
||||||
|
builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
|
||||||
|
});
|
||||||
|
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.AddShardingDbContext<MyDbContext>((conStr, builder) =>
|
||||||
|
{
|
||||||
|
builder.UseSqlServer(conStr).UseLoggerFactory(efLogger);
|
||||||
|
}).Begin(op =>
|
||||||
|
{
|
||||||
|
op.AutoTrackEntity = true;
|
||||||
|
//如果您使用code-first建议选择false
|
||||||
|
op.CreateShardingTableOnStart = true;
|
||||||
|
//如果您使用code-first建议修改为fsle
|
||||||
|
op.EnsureCreatedWithOutShardingTable = true;
|
||||||
|
}).AddShardingTransaction((connection, builder) =>
|
||||||
|
{
|
||||||
|
builder.UseSqlServer(connection).UseLoggerFactory(efLogger);
|
||||||
|
}).AddDefaultDataSource("ds0",
|
||||||
|
"Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;")
|
||||||
|
.AddShardingTableRoute(op =>
|
||||||
|
{
|
||||||
|
op.AddShardingTableRoute<SysUserVirtualTableRoute>();
|
||||||
|
op.AddShardingTableRoute<OrderVirtualTableRoute>();
|
||||||
|
}).End();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseShardingCore();
|
||||||
|
app.UseRouting();
|
||||||
|
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapControllers();
|
||||||
|
});
|
||||||
|
app.InitSeed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Sample.SqlServerShardingTable.Entities;
|
||||||
|
using ShardingCore.Bootstrapers;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable
|
||||||
|
{
|
||||||
|
public static class StartupExtension
|
||||||
|
{
|
||||||
|
public static void UseShardingCore(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.ApplicationServices.GetRequiredService<IShardingBootstrapper>().Start();
|
||||||
|
}
|
||||||
|
public static void InitSeed(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
using (var serviceScope = app.ApplicationServices.CreateScope())
|
||||||
|
{
|
||||||
|
var myDbContext = serviceScope.ServiceProvider.GetRequiredService<MyDbContext>();
|
||||||
|
if (!myDbContext.Set<Setting>().Any())
|
||||||
|
{
|
||||||
|
List<Setting> settings = new List<Setting>(3);
|
||||||
|
settings.Add(new Setting()
|
||||||
|
{
|
||||||
|
Code = "Admin",
|
||||||
|
Name = "AdminName"
|
||||||
|
});
|
||||||
|
settings.Add(new Setting()
|
||||||
|
{
|
||||||
|
Code = "User",
|
||||||
|
Name = "UserName"
|
||||||
|
});
|
||||||
|
settings.Add(new Setting()
|
||||||
|
{
|
||||||
|
Code = "SuperAdmin",
|
||||||
|
Name = "SuperAdminName"
|
||||||
|
});
|
||||||
|
string[] areas = new string[] {"A","B","C" };
|
||||||
|
List<SysUser> users = new List<SysUser>(10);
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
var uer=new SysUser()
|
||||||
|
{
|
||||||
|
Id = i.ToString(),
|
||||||
|
Name = $"MyName{i}",
|
||||||
|
SettingCode = settings[i % 3].Code,
|
||||||
|
Area = areas[i % 3]
|
||||||
|
};
|
||||||
|
users.Add(uer);
|
||||||
|
}
|
||||||
|
List<Order> orders = new List<Order>(300);
|
||||||
|
var begin = new DateTime(2021, 1, 1, 3, 3, 3);
|
||||||
|
for (int i = 0; i < 300; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
var order = new Order()
|
||||||
|
{
|
||||||
|
Id = i.ToString(),
|
||||||
|
Payer = $"{i % 10}",
|
||||||
|
Money = 100+new Random().Next(100,3000),
|
||||||
|
OrderStatus = (OrderStatusEnum)(i % 4 + 1),
|
||||||
|
Area = areas[i % 3],
|
||||||
|
CreationTime = begin.AddDays(i)
|
||||||
|
};
|
||||||
|
orders.Add(order);
|
||||||
|
}
|
||||||
|
myDbContext.AddRange(settings);
|
||||||
|
myDbContext.AddRange(users);
|
||||||
|
myDbContext.AddRange(orders);
|
||||||
|
myDbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
using Sample.SqlServerShardingTable.Entities;
|
||||||
|
using ShardingCore.Core.EntityMetadatas;
|
||||||
|
using ShardingCore.VirtualRoutes.Months;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable.VirtualRoutes
|
||||||
|
{
|
||||||
|
public class OrderVirtualTableRoute:AbstractSimpleShardingMonthKeyDateTimeVirtualTableRoute<Order>
|
||||||
|
{
|
||||||
|
public override DateTime GetBeginTime()
|
||||||
|
{
|
||||||
|
return new DateTime(2021, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Configure(EntityMetadataTableBuilder<Order> builder)
|
||||||
|
{
|
||||||
|
builder.ShardingProperty(o => o.CreationTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Sample.SqlServerShardingTable.Entities;
|
||||||
|
using ShardingCore.Core.EntityMetadatas;
|
||||||
|
using ShardingCore.VirtualRoutes.Mods;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable.VirtualRoutes
|
||||||
|
{
|
||||||
|
public class SysUserVirtualTableRoute:AbstractSimpleShardingModKeyStringVirtualTableRoute<SysUser>
|
||||||
|
{
|
||||||
|
public SysUserVirtualTableRoute() : base(2, 3)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Configure(EntityMetadataTableBuilder<SysUser> builder)
|
||||||
|
{
|
||||||
|
builder.ShardingProperty(o => o.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Sample.SqlServerShardingTable
|
||||||
|
{
|
||||||
|
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": "*"
|
||||||
|
}
|
|
@ -39,8 +39,8 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||||
|
|
||||||
|
|
||||||
var queryEntities = routeRuleContext.QueryEntities.Where(o => _entityMetadataManager.IsShardingDataSource(o)).ToList();
|
var queryEntities = routeRuleContext.QueryEntities.Where(o => _entityMetadataManager.IsShardingDataSource(o)).ToList();
|
||||||
if (queryEntities.Count > 1)
|
//if (queryEntities.Count > 1)
|
||||||
throw new ShardingCoreNotSupportedException($"{routeRuleContext.Queryable.ShardingPrint()}");
|
// throw new ShardingCoreNotSupportedException($"{routeRuleContext.Queryable.ShardingPrint()}");
|
||||||
foreach (var queryEntity in queryEntities)
|
foreach (var queryEntity in queryEntities)
|
||||||
{
|
{
|
||||||
var dataSourceConfigs = _virtualDataSource.RouteTo(queryEntity,new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
|
var dataSourceConfigs = _virtualDataSource.RouteTo(queryEntity,new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
|
||||||
|
|
Loading…
Reference in New Issue