仅分库track

This commit is contained in:
xuejiaming 2023-07-19 15:13:48 +08:00
parent 4f31e8f411
commit afef8e7d8b
16 changed files with 342 additions and 25 deletions

View File

@ -73,6 +73,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore3", "src3\Shard
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore2", "src2\ShardingCore2\ShardingCore2.csproj", "{F0393C32-2285-4F47-AC61-C1BA1CAC269D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.MySQLDataSourceOnly", "samples\Sample.MySQLDataSourceOnly\Sample.MySQLDataSourceOnly.csproj", "{3B5A4B03-5190-41A8-8E4B-F95A79A5C018}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -187,6 +189,10 @@ Global
{F0393C32-2285-4F47-AC61-C1BA1CAC269D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F0393C32-2285-4F47-AC61-C1BA1CAC269D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F0393C32-2285-4F47-AC61-C1BA1CAC269D}.Release|Any CPU.Build.0 = Release|Any CPU
{3B5A4B03-5190-41A8-8E4B-F95A79A5C018}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B5A4B03-5190-41A8-8E4B-F95A79A5C018}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B5A4B03-5190-41A8-8E4B-F95A79A5C018}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B5A4B03-5190-41A8-8E4B-F95A79A5C018}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -219,6 +225,7 @@ Global
{E5E48D52-CAD3-42F0-82CD-A2A6180F3C4D} = {53D07876-A791-46AE-8381-08557593693D}
{B59909AD-8885-40F3-9454-6C8433463BCC} = {51E1D067-3E81-4815-94F2-F8ABBE80881E}
{F0393C32-2285-4F47-AC61-C1BA1CAC269D} = {B11D7DF7-A907-407E-8BF1-35B430413557}
{3B5A4B03-5190-41A8-8E4B-F95A79A5C018} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8C07A667-E8B4-43C7-8053-721584BAD291}

View File

@ -0,0 +1,38 @@
using Microsoft.AspNetCore.Mvc;
using Sample.MySQLDataSourceOnly.Domain;
namespace Sample.MySQLDataSourceOnly.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;
private readonly MyDbContext _myDbContext;
public WeatherForecastController(ILogger<WeatherForecastController> logger,MyDbContext myDbContext)
{
_logger = logger;
_myDbContext = myDbContext;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
var user = _myDbContext.Set<SysUser>().FirstOrDefault(o=>o.Id=="1");
user.Name = "456"+DateTime.Now.ToString();
_myDbContext.SaveChanges();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}

View File

@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding;
namespace Sample.MySQLDataSourceOnly.Domain;
public class MyDbContext : AbstractShardingDbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
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));
});
}
}

View File

@ -0,0 +1,8 @@
namespace Sample.MySQLDataSourceOnly.Domain;
public class SysUser
{
public string Id { get; set; }
public string Name { get; set; }
public string Area { get; set; }
}

View File

@ -0,0 +1,55 @@
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions;
namespace Sample.MySQLDataSourceOnly.Domain;
public class SysUserVirtualDataSourceRoute : AbstractShardingOperatorVirtualDataSourceRoute<SysUser, string>
{
private readonly List<string> _dataSources = new List<string>()
{
"A", "B", "C"
};
protected 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;
}
public override 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<SysUser> builder)
{
builder.ShardingProperty(o => o.Area);
}
}

View File

@ -0,0 +1,77 @@
using Microsoft.EntityFrameworkCore;
using Sample.MySQLDataSourceOnly.Domain;
using ShardingCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddShardingDbContext<MyDbContext>()
.UseRouteConfig(o =>
{
//o.CreateShardingTableOnStart = true;
//o.EnsureCreatedWithOutShardingTable = true;
o.AddShardingDataSourceRoute<SysUserVirtualDataSourceRoute>();
})
.UseConfig((sp,op) =>
{
var loggerFactory = sp.ApplicationServiceProvider.GetService<ILoggerFactory>();
//op.ConfigId = "c1";
op.UseShardingQuery((conStr, builder) =>
{
builder.UseMySql(conStr,new MySqlServerVersion(new Version()))
.UseLoggerFactory(loggerFactory).EnableSensitiveDataLogging();
});
op.UseShardingTransaction((connection, builder) =>
{
builder.UseMySql(connection,new MySqlServerVersion(new Version()))
.UseLoggerFactory(loggerFactory).EnableSensitiveDataLogging();;
});
//op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MyDbContext>());
op.AddDefaultDataSource("A", @"server=127.0.0.1;port=3306;database=onlyds1;userid=root;password=root;");
op.AddExtraDataSource(sp =>
{
return new Dictionary<string, string>()
{
{
"B",
@"server=127.0.0.1;port=3306;database=onlyds2;userid=root;password=root;"
},
{
"C",
@"server=127.0.0.1;port=3306;database=onlyds3;userid=root;password=root;"
},
};
});
}).AddShardingCore();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Services.UseAutoTryCompensateTable();
// using (var serviceScope = app.Services.CreateScope())
// {
// var myDbContext = serviceScope.ServiceProvider.GetService<MyDbContext>();
// myDbContext.Database.EnsureCreated();
// myDbContext.Add(new SysUser() { Id = "1", Area = "A", Name = "name" });
// myDbContext.SaveChanges();
// }
app.Run();

View File

@ -0,0 +1,41 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:35669",
"sslPort": 44323
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5029",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7187;http://localhost:5029",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,12 @@
namespace Sample.MySQLDataSourceOnly;
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary { get; set; }
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -420,5 +420,18 @@ namespace Sample.MySql.Controllers
await _unShardingDbContext.SaveChangesAsync();
return Ok();
}
[HttpGet]
public async Task<IActionResult> Get16()
{
var sysUserMod = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync();
sysUserMod.Age = new Random().Next(1,999);
await _defaultTableDbContext.SaveChangesAsync();
// var sysUserMods1 = await _defaultTableDbContext.Set<SysUserMod>().FromSqlRaw("select * from SysUserMod where id='2'").ToListAsync();
// var sysUserMods2 = await _defaultTableDbContext.Set<SysTest>().FromSqlRaw("select * from SysTest where id='2'").ToListAsync();
return Ok();
}
}
}

View File

@ -116,6 +116,7 @@ namespace Sample.MySql
var logger = sp.ApplicationServiceProvider.GetService<ILogger<Startup>>();
logger.LogInformation(conStr);
builder.UseMySql(conStr, new MySqlServerVersion(new Version()))
// .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
.UseLoggerFactory(loggerFactory1)
.EnableSensitiveDataLogging();
//.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
@ -124,6 +125,7 @@ namespace Sample.MySql
{
builder
.UseMySql(connection, new MySqlServerVersion(new Version()))
// .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
.UseLoggerFactory(loggerFactory1)
.EnableSensitiveDataLogging();
//.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
@ -247,6 +249,12 @@ namespace Sample.MySql
// DynamicShardingHelper.DynamicAppendDataSource<DefaultShardingDbContext>($"c0",$"ds{i}",$"server=127.0.0.1;port=3306;database=dbdbd{i};userid=root;password=root;");
//
// }
// using (var scope = app.ApplicationServices.CreateScope())
// {
// var defaultShardingDbContext = scope.ServiceProvider.GetRequiredService<DefaultShardingDbContext>();
// var addMonths = DateTime.Now.AddMonths(-5);
// defaultShardingDbContext.Set<SysUserLogByMonth>().Where(o => o.Time >= addMonths).Any();
// }
app.DbSeed();
}
}

View File

@ -103,9 +103,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
//如果笛卡尔积
var sqlRouteUnits = new List<ISqlRouteUnit>(31);
int dataSourceCount = 0;
bool isCrossTable = false;
bool existCrossTableTails = false;
var dataSourceSet = new HashSet<string>();
foreach (var dataSourceName in tableRouteRuleContext.DataSourceRouteResult.IntersectDataSources)
{
if (routeMaps.ContainsKey(dataSourceName))
@ -118,7 +118,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
var tableRouteResults = GetTableRouteResults(tableRouteRuleContext, routeResults);
if (tableRouteResults.IsNotEmpty())
{
dataSourceCount++;
dataSourceSet.Add(dataSourceName);
if (tableRouteResults.Length > 1)
{
isCrossTable = true;
@ -140,12 +140,13 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
}
}else if (onlyShardingDataSource)
{
dataSourceSet.Add(dataSourceName);
var tableRouteResult = new TableRouteResult(queryEntities.Keys.Select(o=>new TableRouteUnit(dataSourceName,String.Empty,o )).ToList());
sqlRouteUnits.Add(new SqlRouteUnit(dataSourceName, tableRouteResult));
}
}
return new ShardingRouteResult(sqlRouteUnits, sqlRouteUnits.Count == 0, dataSourceCount > 1, isCrossTable,
return new ShardingRouteResult(sqlRouteUnits, sqlRouteUnits.Count == 0, dataSourceSet.Count > 1, isCrossTable,
existCrossTableTails);
//
// var sqlRouteUnits = tableRouteRuleContext.DataSourceRouteResult.IntersectDataSources.SelectMany(

View File

@ -246,7 +246,7 @@ namespace ShardingCore.Sharding.ShardingExecutors
/// <returns></returns>
public bool IsParallelQuery()
{
return _isCrossTable || _existCrossTableTails || _queryCompilerContext.IsParallelQuery();
return _isCrossTable || _existCrossTableTails || _isCrossDataSource || _queryCompilerContext.IsParallelQuery();
}
public int? GetFixedTake()

View File

@ -134,23 +134,23 @@ namespace ShardingCore.Sharding
return dbContext;
}
/// <summary>
/// 因为并发查询情况下那么你是内存就是内存你是流式就是流式
/// 如果不是并发查询的情况下系统会将当前dbcontext进行利用起来所以只能是流式
/// </summary>
/// <param name="connectionMode"></param>
/// <returns></returns>
public ConnectionModeEnum RealConnectionMode(ConnectionModeEnum connectionMode)
{
if (IsParallelQuery())
{
return connectionMode;
}
else
{
return ConnectionModeEnum.MEMORY_STRICTLY;
}
}
// /// <summary>
// /// 因为并发查询情况下那么你是内存就是内存你是流式就是流式
// /// 如果不是并发查询的情况下系统会将当前dbcontext进行利用起来所以只能是流式
// /// </summary>
// /// <param name="connectionMode"></param>
// /// <returns></returns>
// public ConnectionModeEnum RealConnectionMode(ConnectionModeEnum connectionMode)
// {
// if (IsParallelQuery())
// {
// return connectionMode;
// }
// else
// {
// return ConnectionModeEnum.MEMORY_STRICTLY;
// }
// }
//public IRouteTail Create(TableRouteResult tableRouteResult)
//{
@ -279,10 +279,6 @@ namespace ShardingCore.Sharding
{
if (!IsParallelQuery())
{
if (IsCrossDataSource)
{
return true;
}
return false;
}
return QueryTrack() && _trackerManager.EntityUseTrack(entityType);