Merge branch 'sharding-6'
# Conflicts: # samples/Sample.MySql/Startup.cs # src/ShardingCore/EFCores/OptionsExtensions/ShardingWrapOptionsExtension.cs # src/ShardingCore/ShardingCoreExtension.cs
This commit is contained in:
commit
8795cca4f4
|
@ -1,73 +1,73 @@
|
|||
using System.Data.Common;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
|
||||
namespace Sample.MultiConfig.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CommonController : ControllerBase
|
||||
{
|
||||
private readonly IVirtualDataSourceManager<MultiConfigDbContext> _virtualDataSourceManager;
|
||||
|
||||
public CommonController(IVirtualDataSourceManager<MultiConfigDbContext> virtualDataSourceManager)
|
||||
{
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
}
|
||||
public async Task<IActionResult> DynamicAdd(string configId)
|
||||
{
|
||||
var flag = DynamicDataSourceHelper.DynamicAppendVirtualDataSource(new MySqlConfigurationParam(configId));
|
||||
return Ok(flag?"成功":"失败");
|
||||
}
|
||||
}
|
||||
|
||||
public class MySqlConfigurationParam : AbstractVirtualDataSourceConfigurationParams<MultiConfigDbContext>
|
||||
{
|
||||
public override string ConfigId { get; }
|
||||
public override int Priority { get; }
|
||||
public override string DefaultDataSourceName { get; }
|
||||
public override string DefaultConnectionString { get; }
|
||||
public override IDictionary<string, ReadNode[]> ReadWriteNodeSeparationConfigs { get; }
|
||||
public override ReadStrategyEnum? ReadStrategy { get; }
|
||||
public override bool? ReadWriteDefaultEnable { get; }
|
||||
public override int? ReadWriteDefaultPriority { get; }
|
||||
public override ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
|
||||
public MySqlConfigurationParam(string configId)
|
||||
{
|
||||
ConfigId = configId;
|
||||
DefaultDataSourceName = "ds0";
|
||||
DefaultConnectionString = $"server=127.0.0.1;port=3306;database=MultiConfigSharding{configId};userid=root;password=L6yBtV6qNENrwBy7;";
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
dbContextOptionsBuilder.UseMySql(connectionString,new MySqlServerVersion(new Version()));
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
dbContextOptionsBuilder.UseMySql(dbConnection, new MySqlServerVersion(new Version()));
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public override void UseShellDbContextOptionBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void UseExecutorDbContextOptionBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// using System.Data.Common;
|
||||
// using Microsoft.AspNetCore.Mvc;
|
||||
// using Microsoft.EntityFrameworkCore;
|
||||
// using ShardingCore.Core;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
// using ShardingCore.DynamicDataSources;
|
||||
// using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
// using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
// using ShardingCore.TableExists.Abstractions;
|
||||
//
|
||||
// namespace Sample.MultiConfig.Controllers
|
||||
// {
|
||||
// [ApiController]
|
||||
// [Route("[controller]/[action]")]
|
||||
// public class CommonController : ControllerBase
|
||||
// {
|
||||
// private readonly IVirtualDataSourceManager<MultiConfigDbContext> _virtualDataSourceManager;
|
||||
//
|
||||
// public CommonController(IVirtualDataSourceManager<MultiConfigDbContext> virtualDataSourceManager)
|
||||
// {
|
||||
// _virtualDataSourceManager = virtualDataSourceManager;
|
||||
// }
|
||||
// public async Task<IActionResult> DynamicAdd(string configId)
|
||||
// {
|
||||
// var flag = DynamicDataSourceHelper.DynamicAppendVirtualDataSource(new MySqlConfigurationParam(configId));
|
||||
// return Ok(flag?"成功":"失败");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public class MySqlConfigurationParam : AbstractVirtualDataSourceConfigurationParams<MultiConfigDbContext>
|
||||
// {
|
||||
// public override string ConfigId { get; }
|
||||
// public override int Priority { get; }
|
||||
// public override string DefaultDataSourceName { get; }
|
||||
// public override string DefaultConnectionString { get; }
|
||||
// public override IDictionary<string, ReadNode[]> ReadWriteNodeSeparationConfigs { get; }
|
||||
// public override ReadStrategyEnum? ReadStrategy { get; }
|
||||
// public override bool? ReadWriteDefaultEnable { get; }
|
||||
// public override int? ReadWriteDefaultPriority { get; }
|
||||
// public override ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
//
|
||||
// public MySqlConfigurationParam(string configId)
|
||||
// {
|
||||
// ConfigId = configId;
|
||||
// DefaultDataSourceName = "ds0";
|
||||
// DefaultConnectionString = $"server=127.0.0.1;port=3306;database=MultiConfigSharding{configId};userid=root;password=L6yBtV6qNENrwBy7;";
|
||||
// }
|
||||
//
|
||||
// public override DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
// DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
// {
|
||||
// dbContextOptionsBuilder.UseMySql(connectionString,new MySqlServerVersion(new Version()));
|
||||
// return dbContextOptionsBuilder;
|
||||
// }
|
||||
//
|
||||
// public override DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
// DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
// {
|
||||
// dbContextOptionsBuilder.UseMySql(dbConnection, new MySqlServerVersion(new Version()));
|
||||
// return dbContextOptionsBuilder;
|
||||
// }
|
||||
//
|
||||
// public override void UseShellDbContextOptionBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public override void UseExecutorDbContextOptionBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.MultiConfig.Domain.Entities;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
|
||||
namespace Sample.MultiConfig.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class TestController:ControllerBase
|
||||
{
|
||||
private readonly MultiConfigDbContext _multiConfigDbContext;
|
||||
private readonly IVirtualTableManager<MultiConfigDbContext> _virtualTableManager;
|
||||
|
||||
public TestController(MultiConfigDbContext multiConfigDbContext,IVirtualTableManager<MultiConfigDbContext> virtualTableManager)
|
||||
{
|
||||
_multiConfigDbContext = multiConfigDbContext;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
public async Task<IActionResult> Add()
|
||||
{
|
||||
var order = new Order();
|
||||
order.Id = Guid.NewGuid().ToString("n");
|
||||
order.Name = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
order.CreateTime=DateTime.Now;
|
||||
await _multiConfigDbContext.AddAsync(order);
|
||||
await _multiConfigDbContext.SaveChangesAsync();
|
||||
return Ok();
|
||||
}
|
||||
public async Task<IActionResult> Query()
|
||||
{
|
||||
var listAsync = await _multiConfigDbContext.Set<Order>().ToListAsync();
|
||||
return Ok(listAsync);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// using Microsoft.AspNetCore.Mvc;
|
||||
// using Microsoft.EntityFrameworkCore;
|
||||
// using Sample.MultiConfig.Domain.Entities;
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
//
|
||||
// namespace Sample.MultiConfig.Controllers
|
||||
// {
|
||||
// [ApiController]
|
||||
// [Route("[controller]/[action]")]
|
||||
// public class TestController:ControllerBase
|
||||
// {
|
||||
// private readonly MultiConfigDbContext _multiConfigDbContext;
|
||||
// private readonly IVirtualTableManager<MultiConfigDbContext> _virtualTableManager;
|
||||
//
|
||||
// public TestController(MultiConfigDbContext multiConfigDbContext,IVirtualTableManager<MultiConfigDbContext> virtualTableManager)
|
||||
// {
|
||||
// _multiConfigDbContext = multiConfigDbContext;
|
||||
// _virtualTableManager = virtualTableManager;
|
||||
// }
|
||||
// public async Task<IActionResult> Add()
|
||||
// {
|
||||
// var order = new Order();
|
||||
// order.Id = Guid.NewGuid().ToString("n");
|
||||
// order.Name = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||
// order.CreateTime=DateTime.Now;
|
||||
// await _multiConfigDbContext.AddAsync(order);
|
||||
// await _multiConfigDbContext.SaveChangesAsync();
|
||||
// return Ok();
|
||||
// }
|
||||
// public async Task<IActionResult> Query()
|
||||
// {
|
||||
// var listAsync = await _multiConfigDbContext.Set<Order>().ToListAsync();
|
||||
// return Ok(listAsync);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
namespace Sample.MultiConfig.Middlewares
|
||||
{
|
||||
public class TenantSelectMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IVirtualDataSourceManager<MultiConfigDbContext> _virtualDataSourceManager;
|
||||
|
||||
public TenantSelectMiddleware(RequestDelegate next, IVirtualDataSourceManager<MultiConfigDbContext> virtualDataSourceManager)
|
||||
{
|
||||
_next = next;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 1.中间件的方法必须叫Invoke,且为public,非static。
|
||||
/// 2.Invoke方法第一个参数必须是HttpContext类型。
|
||||
/// 3.Invoke方法必须返回Task。
|
||||
/// 4.Invoke方法可以有多个参数,除HttpContext外其它参数会尝试从依赖注入容器中获取。
|
||||
/// 5.Invoke方法不能有重载。
|
||||
/// </summary>
|
||||
/// Author : Napoleon
|
||||
/// Created : 2020/1/30 21:30
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (context.Request.Path.ToString().StartsWith("/test", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
if (!context.Request.Headers.ContainsKey("TenantId") || !_virtualDataSourceManager.ContansConfigId(context.Request.Headers["TenantId"]))
|
||||
{
|
||||
context.Response.StatusCode = 403; //UnAuthorized
|
||||
await context.Response.WriteAsync("403 not found TenantId");
|
||||
return;
|
||||
}
|
||||
|
||||
using (_virtualDataSourceManager.CreateScope(context.Request.Headers["TenantId"]))
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
//
|
||||
// namespace Sample.MultiConfig.Middlewares
|
||||
// {
|
||||
// public class TenantSelectMiddleware
|
||||
// {
|
||||
// private readonly RequestDelegate _next;
|
||||
// private readonly IVirtualDataSourceManager<MultiConfigDbContext> _virtualDataSourceManager;
|
||||
//
|
||||
// public TenantSelectMiddleware(RequestDelegate next, IVirtualDataSourceManager<MultiConfigDbContext> virtualDataSourceManager)
|
||||
// {
|
||||
// _next = next;
|
||||
// _virtualDataSourceManager = virtualDataSourceManager;
|
||||
// }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 1.中间件的方法必须叫Invoke,且为public,非static。
|
||||
// /// 2.Invoke方法第一个参数必须是HttpContext类型。
|
||||
// /// 3.Invoke方法必须返回Task。
|
||||
// /// 4.Invoke方法可以有多个参数,除HttpContext外其它参数会尝试从依赖注入容器中获取。
|
||||
// /// 5.Invoke方法不能有重载。
|
||||
// /// </summary>
|
||||
// /// Author : Napoleon
|
||||
// /// Created : 2020/1/30 21:30
|
||||
// public async Task Invoke(HttpContext context)
|
||||
// {
|
||||
// if (context.Request.Path.ToString().StartsWith("/test", StringComparison.CurrentCultureIgnoreCase))
|
||||
// {
|
||||
// if (!context.Request.Headers.ContainsKey("TenantId") || !_virtualDataSourceManager.ContansConfigId(context.Request.Headers["TenantId"]))
|
||||
// {
|
||||
// context.Response.StatusCode = 403; //UnAuthorized
|
||||
// await context.Response.WriteAsync("403 not found TenantId");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// using (_virtualDataSourceManager.CreateScope(context.Request.Headers["TenantId"]))
|
||||
// {
|
||||
// await _next(context);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// await _next(context);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,64 +1,60 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.MultiConfig;
|
||||
using Sample.MultiConfig.Middlewares;
|
||||
using ShardingCore;
|
||||
using ShardingCore.Bootstrappers;
|
||||
using ShardingCore.TableExists;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
ILoggerFactory efLogger = LoggerFactory.Create(builder =>
|
||||
{
|
||||
builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
|
||||
});
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddShardingDbContext<MultiConfigDbContext>()
|
||||
.AddEntityConfig(op =>
|
||||
{
|
||||
op.CreateShardingTableOnStart = true;
|
||||
op.EnsureCreatedWithOutShardingTable = true;
|
||||
op.AddShardingTableRoute<OrderIdModVirtualTableRoute>();
|
||||
})
|
||||
.AddConfig(op =>
|
||||
{
|
||||
op.ConfigId = "c1";
|
||||
op.UseShardingQuery((conStr, b) =>
|
||||
{
|
||||
b.UseSqlServer(conStr).UseLoggerFactory(efLogger);
|
||||
});
|
||||
op.UseShardingTransaction((conn, b) =>
|
||||
{
|
||||
b.UseSqlServer(conn).UseLoggerFactory(efLogger);
|
||||
});
|
||||
op.AddDefaultDataSource("ds0",
|
||||
"Data Source=localhost;Initial Catalog=MultiConfigSharding;Integrated Security=True;");
|
||||
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MultiConfigDbContext>());
|
||||
})
|
||||
.AddConfig(op =>
|
||||
{
|
||||
op.ConfigId = "c2";
|
||||
op.UseShardingQuery((conStr, b) =>
|
||||
{
|
||||
b.UseMySql(conStr, new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger);
|
||||
});
|
||||
op.UseShardingTransaction((conn, b) =>
|
||||
{
|
||||
b.UseMySql(conn, new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger);
|
||||
});
|
||||
op.AddDefaultDataSource("ds0",
|
||||
"server=127.0.0.1;port=3306;database=MultiConfigSharding;userid=root;password=L6yBtV6qNENrwBy7;");
|
||||
op.ReplaceTableEnsureManager(sp => new MySqlTableEnsureManager<MultiConfigDbContext>());
|
||||
}).EnsureMultiConfig();
|
||||
|
||||
//
|
||||
// // Add services to the container.
|
||||
//
|
||||
// ILoggerFactory efLogger = LoggerFactory.Create(builder =>
|
||||
// {
|
||||
// builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
|
||||
// });
|
||||
// builder.Services.AddControllers();
|
||||
// builder.Services.AddShardingDbContext<MultiConfigDbContext>()
|
||||
// .AddEntityConfig(op =>
|
||||
// {
|
||||
// op.AddShardingTableRoute<OrderIdModVirtualTableRoute>();
|
||||
// })
|
||||
// .AddConfig(op =>
|
||||
// {
|
||||
// // op.ConfigId = "c1";
|
||||
// op.UseShardingQuery((conStr, b) =>
|
||||
// {
|
||||
// b.UseSqlServer(conStr).UseLoggerFactory(efLogger);
|
||||
// });
|
||||
// op.UseShardingTransaction((conn, b) =>
|
||||
// {
|
||||
// b.UseSqlServer(conn).UseLoggerFactory(efLogger);
|
||||
// });
|
||||
// op.AddDefaultDataSource("ds0",
|
||||
// "Data Source=localhost;Initial Catalog=MultiConfigSharding;Integrated Security=True;");
|
||||
// // op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<MultiConfigDbContext>());
|
||||
// })
|
||||
// .AddConfig(op =>
|
||||
// {
|
||||
// op.ConfigId = "c2";
|
||||
// op.UseShardingQuery((conStr, b) =>
|
||||
// {
|
||||
// b.UseMySql(conStr, new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger);
|
||||
// });
|
||||
// op.UseShardingTransaction((conn, b) =>
|
||||
// {
|
||||
// b.UseMySql(conn, new MySqlServerVersion(new Version())).UseLoggerFactory(efLogger);
|
||||
// });
|
||||
// op.AddDefaultDataSource("ds0",
|
||||
// "server=127.0.0.1;port=3306;database=MultiConfigSharding;userid=root;password=L6yBtV6qNENrwBy7;");
|
||||
// op.ReplaceTableEnsureManager(sp => new MySqlTableEnsureManager<MultiConfigDbContext>());
|
||||
// }).EnsureMultiConfig();
|
||||
//
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
app.Services.GetRequiredService<IShardingBootstrapper>().Start();
|
||||
//
|
||||
// // Configure the HTTP request pipeline.
|
||||
// app.Services.GetRequiredService<IShardingBootstrapper>().Start();
|
||||
app.UseAuthorization();
|
||||
app.UseMiddleware<TenantSelectMiddleware>();
|
||||
|
||||
// app.UseMiddleware<TenantSelectMiddleware>();
|
||||
//
|
||||
app.MapControllers();
|
||||
|
||||
//
|
||||
app.Run();
|
||||
|
|
|
@ -1,74 +1,63 @@
|
|||
// using Microsoft.AspNetCore.Mvc;
|
||||
// using Microsoft.Extensions.Logging;
|
||||
// using System;
|
||||
// using System.Collections.Generic;
|
||||
// using System.Linq;
|
||||
// using System.Threading.Tasks;
|
||||
// using Microsoft.EntityFrameworkCore;
|
||||
// using Sample.MySql.DbContexts;
|
||||
// using Sample.MySql.Domain.Entities;
|
||||
// using ShardingCore.Core.PhysicTables;
|
||||
// using ShardingCore.Core.VirtualTables;
|
||||
// using ShardingCore.DbContexts.VirtualDbContexts;
|
||||
// using ShardingCore.Extensions;
|
||||
// using ShardingCore.TableCreator;
|
||||
//
|
||||
// namespace Sample.MySql.Controllers
|
||||
// {
|
||||
// [ApiController]
|
||||
// [Route("[controller]/[action]")]
|
||||
// public class WeatherForecastController : ControllerBase
|
||||
// {
|
||||
//
|
||||
// private readonly DefaultTableDbContext _defaultTableDbContext;
|
||||
// private readonly IVirtualTableManager _virtualTableManager;
|
||||
// private readonly IShardingTableCreator _tableCreator;
|
||||
//
|
||||
// public WeatherForecastController(DefaultTableDbContext defaultTableDbContext,IVirtualTableManager virtualTableManager, IShardingTableCreator tableCreator)
|
||||
// {
|
||||
// _defaultTableDbContext = defaultTableDbContext;
|
||||
// _virtualTableManager = virtualTableManager;
|
||||
// _tableCreator = tableCreator;
|
||||
// }
|
||||
//
|
||||
// [HttpGet]
|
||||
// public async Task<IActionResult> Get()
|
||||
// {
|
||||
// var taleAllTails = _virtualTableManager.GetVirtualTable(typeof(SysUserLogByMonth)).GetTableAllTails();
|
||||
//
|
||||
//
|
||||
// var result = await _defaultTableDbContext.Set<SysTest>().AnyAsync();
|
||||
// var result1 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2" || o.Id == "3").ToShardingListAsync();
|
||||
// var result2 = await _defaultTableDbContext.Set<SysUserLogByMonth>().Skip(1).Take(10).ToShardingListAsync();
|
||||
// var shardingFirstOrDefaultAsync = await _defaultTableDbContext.Set<SysUserLogByMonth>().ShardingFirstOrDefaultAsync();
|
||||
// var shardingCountAsync = await _defaultTableDbContext.Set<SysUserMod>().ShardingCountAsync();
|
||||
// var shardingCountAsyn2c = _defaultTableDbContext.Set<SysUserLogByMonth>().ShardingCount();
|
||||
//
|
||||
// return Ok(result1);
|
||||
// }
|
||||
// [HttpGet]
|
||||
// public async Task<IActionResult> Get1()
|
||||
// {
|
||||
// var allVirtualTables = _virtualTableManager.GetAllVirtualTables();
|
||||
// foreach (var virtualTable in allVirtualTables)
|
||||
// {
|
||||
// if (virtualTable.EntityType == typeof(SysUserLogByMonth))
|
||||
// {
|
||||
// var now = DateTime.Now.Date.AddMonths(2);
|
||||
// var tail = virtualTable.GetVirtualRoute().ShardingKeyToTail(now);
|
||||
// try
|
||||
// {
|
||||
// _virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, tail));
|
||||
// _tableCreator.CreateTable<SysUserLogByMonth>(tail);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// //ignore
|
||||
// Console.WriteLine(e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return Ok();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.MySql.DbContexts;
|
||||
using Sample.MySql.Domain.Entities;
|
||||
using ShardingCore.TableCreator;
|
||||
|
||||
namespace Sample.MySql.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
|
||||
private readonly DefaultShardingDbContext _defaultTableDbContext;
|
||||
|
||||
public WeatherForecastController(DefaultShardingDbContext defaultTableDbContext)
|
||||
{
|
||||
_defaultTableDbContext = defaultTableDbContext;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
var result = await _defaultTableDbContext.Set<SysTest>().AnyAsync();
|
||||
var result1 = await _defaultTableDbContext.Set<SysUserMod>().Where(o => o.Id == "2" || o.Id == "3").ToListAsync();
|
||||
var result2 = await _defaultTableDbContext.Set<SysUserLogByMonth>().Skip(1).Take(10).ToListAsync();
|
||||
var shardingFirstOrDefaultAsync = await _defaultTableDbContext.Set<SysUserLogByMonth>().ToListAsync();
|
||||
var shardingCountAsync = await _defaultTableDbContext.Set<SysUserMod>().CountAsync();
|
||||
var shardingCountAsyn2c = _defaultTableDbContext.Set<SysUserLogByMonth>().Count();
|
||||
|
||||
return Ok(result1);
|
||||
}
|
||||
// [HttpGet]
|
||||
// public async Task<IActionResult> Get1()
|
||||
// {
|
||||
// var allVirtualTables = _virtualTableManager.GetAllVirtualTables();
|
||||
// foreach (var virtualTable in allVirtualTables)
|
||||
// {
|
||||
// if (virtualTable.EntityType == typeof(SysUserLogByMonth))
|
||||
// {
|
||||
// var now = DateTime.Now.Date.AddMonths(2);
|
||||
// var tail = virtualTable.GetVirtualRoute().ShardingKeyToTail(now);
|
||||
// try
|
||||
// {
|
||||
// _virtualTableManager.AddPhysicTable(virtualTable, new DefaultPhysicTable(virtualTable, tail));
|
||||
// _tableCreator.CreateTable<SysUserLogByMonth>(tail);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// //ignore
|
||||
// Console.WriteLine(e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return Ok();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,6 @@ namespace Sample.MySql
|
|||
*/
|
||||
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())
|
||||
|
|
|
@ -9,7 +9,6 @@ namespace Sample.MySql.Domain.Entities
|
|||
public class SysUserLogByMonth
|
||||
{
|
||||
public string Id { get; set; }
|
||||
[ShardingTableKey]
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ namespace Sample.MySql.Domain.Entities
|
|||
/// <summary>
|
||||
/// 用户Id用于分表
|
||||
/// </summary>
|
||||
[ShardingTableKey]
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// 用户名称
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Sample.MySql.Shardings
|
|||
|
||||
public override void Configure(EntityMetadataTableBuilder<SysUserLogByMonth> builder)
|
||||
{
|
||||
|
||||
builder.ShardingProperty(o => o.Time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ namespace Sample.MySql.Shardings
|
|||
|
||||
public override void Configure(EntityMetadataTableBuilder<SysUserMod> builder)
|
||||
{
|
||||
|
||||
builder.ShardingProperty(o => o.Id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,18 +1,12 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using MySqlConnector;
|
||||
using Sample.MySql.DbContexts;
|
||||
using Sample.MySql.Shardings;
|
||||
using ShardingCore;
|
||||
using ShardingCore.EFCores.OptionsExtensions;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.TableExists;
|
||||
using ShardingCore.Bootstrappers;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace Sample.MySql
|
||||
{
|
||||
|
@ -43,67 +37,80 @@ namespace Sample.MySql
|
|||
// op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
// op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||
// });
|
||||
// services.AddSingleton<IShardingRuntimeContext, ShardingRuntimeContext>();
|
||||
services.AddShardingDbContext<DefaultShardingDbContext>()
|
||||
.AddEntityConfig(o =>
|
||||
{
|
||||
o.CreateDataBaseOnlyOnStart = true;
|
||||
o.CreateShardingTableOnStart = true;
|
||||
o.EnsureCreatedWithOutShardingTable = true;
|
||||
o.IgnoreCreateTableError = true;
|
||||
o.AddShardingTableRoute<SysUserLogByMonthRoute>();
|
||||
o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
|
||||
o.UseShardingQuery((conStr, builder) =>
|
||||
{
|
||||
builder.UseMySql(conStr, new MySqlServerVersion(new Version())
|
||||
,b=>b.EnableRetryOnFailure()
|
||||
)
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
|
||||
//builder.UseMySql(conStr, new MySqlServerVersion(new Version()));
|
||||
});
|
||||
o.UseShardingTransaction((connection, builder) =>
|
||||
{
|
||||
builder.UseMySql(connection, new MySqlServerVersion(new Version())
|
||||
,b=>b.EnableRetryOnFailure()
|
||||
)
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
|
||||
});
|
||||
})
|
||||
.AddConfig(op =>
|
||||
{
|
||||
op.ConfigId = "c0";
|
||||
op.AddDefaultDataSource("ds0",
|
||||
"server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
|
||||
|
||||
//op.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=db2;userid=root;password=L6yBtV6qNENrwBy7;")
|
||||
op.ReplaceTableEnsureManager(sp=>new MySqlTableEnsureManager<DefaultShardingDbContext>());
|
||||
}).EnsureConfig();
|
||||
services.AddSingleton<IShardingRuntimeContext>(sp =>
|
||||
{
|
||||
Stopwatch stopwatch=Stopwatch.StartNew();
|
||||
|
||||
var shardingRuntimeContext = new ShardingRuntimeBuilder<DefaultShardingDbContext>()
|
||||
.UseRouteConfig(o =>
|
||||
{
|
||||
o.AddShardingTableRoute<SysUserLogByMonthRoute>();
|
||||
o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
// o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
|
||||
}).UseConfig(o =>
|
||||
{
|
||||
o.UseShardingQuery((conStr,builder)=>
|
||||
{
|
||||
builder.UseMySql(conStr, new MySqlServerVersion(new Version())).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
|
||||
});
|
||||
o.UseShardingTransaction((connection, builder) =>
|
||||
{
|
||||
builder.UseMySql(connection, new MySqlServerVersion(new Version())).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
|
||||
});
|
||||
o.AddDefaultDataSource("ds0","server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
|
||||
})
|
||||
.Build(sp);
|
||||
stopwatch.Stop();
|
||||
Console.WriteLine("ShardingRuntimeContext build:"+stopwatch.ElapsedMilliseconds);
|
||||
return shardingRuntimeContext;
|
||||
});
|
||||
services.AddDbContext<DefaultShardingDbContext>(ShardingCoreExtension.UseDefaultSharding<DefaultShardingDbContext>);
|
||||
// services.AddShardingDbContext<DefaultShardingDbContext>()
|
||||
// .AddEntityConfig(o =>
|
||||
// {
|
||||
// o.CreateDataBaseOnlyOnStart = true;
|
||||
// o.CreateShardingTableOnStart = true;
|
||||
// o.EnsureCreatedWithOutShardingTable = true;
|
||||
// o.IgnoreCreateTableError = true;
|
||||
// o.AddShardingTableRoute<SysUserLogByMonthRoute>();
|
||||
// o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
// o.AddShardingDataSourceRoute<SysUserModVirtualDataSourceRoute>();
|
||||
// o.UseShardingQuery((conStr, builder) =>
|
||||
// {
|
||||
// builder.UseMySql(conStr, new MySqlServerVersion(new Version())
|
||||
// ,b=>b.EnableRetryOnFailure()
|
||||
// )
|
||||
// .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
|
||||
// //builder.UseMySql(conStr, new MySqlServerVersion(new Version()));
|
||||
// });
|
||||
// o.UseShardingTransaction((connection, builder) =>
|
||||
// {
|
||||
// builder.UseMySql(connection, new MySqlServerVersion(new Version())
|
||||
// ,b=>b.EnableRetryOnFailure()
|
||||
// )
|
||||
// .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
|
||||
// });
|
||||
// })
|
||||
// .AddConfig(op =>
|
||||
// {
|
||||
// op.ConfigId = "c0";
|
||||
// op.AddDefaultDataSource("ds0",
|
||||
// "server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
|
||||
//
|
||||
// //op.AddDefaultDataSource("ds0", "server=127.0.0.1;port=3306;database=db2;userid=root;password=L6yBtV6qNENrwBy7;")
|
||||
// op.ReplaceTableEnsureManager(sp=>new MySqlTableEnsureManager<DefaultShardingDbContext>());
|
||||
// }).EnsureConfig();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
Console.WriteLine("11111");
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseShardingCore();
|
||||
|
||||
// using (var scope = app.ApplicationServices.CreateScope())
|
||||
// {
|
||||
// var dbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
||||
// var shardingRuntimeContext = dbContext.GetService<IShardingRuntimeContext>();
|
||||
// Console.WriteLine("123");
|
||||
// }
|
||||
// using (var scope = app.ApplicationServices.CreateScope())
|
||||
// {
|
||||
// var dbContext = scope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
||||
// var shardingRuntimeContext = dbContext.GetService<IShardingRuntimeContext>();
|
||||
// Console.WriteLine("1231");
|
||||
// }
|
||||
app.ApplicationServices.UseAutoShardingCore();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
|
|
@ -5,21 +5,16 @@ using Sample.SqlServer.DbContexts;
|
|||
using Sample.SqlServer.Domain.Entities;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Extensions.ShardingPageExtensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Extensions.ShardingQueryableExtensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
using ShardingCore.EFCores;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
namespace Sample.SqlServer.Controllers
|
||||
|
@ -36,39 +31,23 @@ namespace Sample.SqlServer.Controllers
|
|||
private readonly DefaultShardingDbContext _defaultTableDbContext;
|
||||
private readonly IShardingRouteManager _shardingRouteManager;
|
||||
private readonly IShardingReadWriteManager _readWriteManager;
|
||||
private readonly IShardingRuntimeContext _shardingRuntimeContext;
|
||||
|
||||
public ValuesController(DefaultShardingDbContext defaultTableDbContext, IShardingRouteManager shardingRouteManager,IShardingReadWriteManager readWriteManager)
|
||||
public ValuesController(DefaultShardingDbContext defaultTableDbContext, IShardingRouteManager shardingRouteManager,IShardingReadWriteManager readWriteManager,IShardingRuntimeContext shardingRuntimeContext)
|
||||
{
|
||||
_defaultTableDbContext = defaultTableDbContext;
|
||||
_ = defaultTableDbContext.Model;
|
||||
_shardingRouteManager = shardingRouteManager;
|
||||
_readWriteManager = readWriteManager;
|
||||
_shardingRuntimeContext = shardingRuntimeContext;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Get2x()
|
||||
{
|
||||
_defaultTableDbContext.ChangeTracker.HasChanges();
|
||||
//var queryable = _defaultTableDbContext.Set<SysUserMod>().Where(o=>true);
|
||||
|
||||
//var tableRouteRuleEngineFactory = ShardingContainer.GetService<ITableRouteRuleEngineFactory<DefaultShardingDbContext>>();
|
||||
//var tableRouteResults = tableRouteRuleEngineFactory.Route(queryable);
|
||||
var virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<DefaultShardingDbContext>>();
|
||||
var virtualTable = virtualTableManager.GetVirtualTable<SysUserMod>();
|
||||
|
||||
var physicTable1s = virtualTable.RouteTo(new ShardingTableRouteConfig(shardingKeyValue: "123"));//获取值为123的所有分片
|
||||
|
||||
Expression<Func<SysUserMod, bool>> where = o => o.Id == "123";
|
||||
var physicTable2s = virtualTable.RouteTo(new ShardingTableRouteConfig(predicate: where));//获取表达式o.Id == "123"的所有路由
|
||||
|
||||
var allPhysicTables = virtualTable.GetAllPhysicTables();
|
||||
|
||||
var virtualTableRoute = virtualTable.GetVirtualRoute();
|
||||
var allTails = virtualTableRoute.GetAllTails();
|
||||
Console.WriteLine("------------------Get2x------------------------");
|
||||
using (var dbContext =
|
||||
DbContextHelper.CreateDbContextByString(
|
||||
"Data Source=localhost;Initial Catalog=ShardingCoreDBXA;Integrated Security=True;"))
|
||||
"Data Source=localhost;Initial Catalog=ShardingCoreDBXA;Integrated Security=True;",_shardingRuntimeContext))
|
||||
{
|
||||
await dbContext.AddAsync(new SysUserMod()
|
||||
{
|
||||
|
|
|
@ -19,13 +19,6 @@ namespace Sample.SqlServer
|
|||
*/
|
||||
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())
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.SqlServer.DbContexts;
|
||||
using ShardingCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
|
||||
namespace Sample.SqlServer
|
||||
{
|
||||
public class DbContextHelper
|
||||
{
|
||||
public static DbContext CreateDbContextByString(string connectionString)
|
||||
public static DbContext CreateDbContextByString(string connectionString,IShardingRuntimeContext shardingRuntimeContext)
|
||||
{
|
||||
var dbContextOptionsBuilder = new DbContextOptionsBuilder<DefaultShardingDbContext>();
|
||||
dbContextOptionsBuilder.UseSqlServer(connectionString).UseSharding<DefaultShardingDbContext>();
|
||||
dbContextOptionsBuilder.UseSqlServer(connectionString).UseSharding<DefaultShardingDbContext>(shardingRuntimeContext);
|
||||
return new DefaultShardingDbContext(dbContextOptionsBuilder.Options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -8,17 +7,10 @@ using Sample.SqlServer.DbContexts;
|
|||
using Sample.SqlServer.Shardings;
|
||||
using Sample.SqlServer.UnionAllMerge;
|
||||
using ShardingCore;
|
||||
using ShardingCore.TableExists;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.EFCores.OptionsExtensions;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
|
||||
namespace Sample.SqlServer
|
||||
{
|
||||
|
@ -41,25 +33,21 @@ namespace Sample.SqlServer
|
|||
//services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx3;Integrated Security=True"));
|
||||
|
||||
services.AddShardingDbContext<DefaultShardingDbContext>()
|
||||
.AddEntityConfig(o =>
|
||||
.UseRouteConfig(o =>
|
||||
{
|
||||
o.ThrowIfQueryRouteNotMatch = false;
|
||||
o.CreateShardingTableOnStart = true;
|
||||
o.EnsureCreatedWithOutShardingTable = true;
|
||||
o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
o.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||
o.AddShardingTableRoute<TestYearShardingVirtualTableRoute>();
|
||||
})
|
||||
.AddConfig(op =>
|
||||
.UseConfig((sp,op) =>
|
||||
{
|
||||
op.ConfigId = "c1";
|
||||
op.MaxQueryConnectionsLimit = 5;
|
||||
op.UseSqlServer(builder =>
|
||||
{
|
||||
var loggerFactory = ShardingContainer.GetService<ILoggerFactory>();
|
||||
var loggerFactory = sp.GetService<ILoggerFactory>();
|
||||
builder.UseLoggerFactory(loggerFactory).UseUnionAllMerge<DefaultShardingDbContext>();
|
||||
});
|
||||
op.ReplaceTableEnsureManager(sp => new SqlServerTableEnsureManager<DefaultShardingDbContext>());
|
||||
op.AddDefaultDataSource("A",
|
||||
"Data Source=localhost;Initial Catalog=ShardingCoreDBXA;Integrated Security=True;"
|
||||
);
|
||||
|
@ -81,7 +69,7 @@ namespace Sample.SqlServer
|
|||
new ReadNode("X","Data Source=localhost;Initial Catalog=ShardingCoreDBXA123;Integrated Security=True;"),
|
||||
}}
|
||||
},ReadStrategyEnum.Loop);
|
||||
}).EnsureConfig();
|
||||
}).AddShardingCore();
|
||||
//services.AddShardingDbContext<DefaultShardingDbContext1>(
|
||||
// (conn, o) =>
|
||||
// o.UseSqlServer(conn).UseLoggerFactory(efLogger)
|
||||
|
@ -137,15 +125,10 @@ namespace Sample.SqlServer
|
|||
}
|
||||
|
||||
|
||||
var startNew = Stopwatch.StartNew();
|
||||
startNew.Start();
|
||||
app.UseShardingCore();
|
||||
startNew.Stop();
|
||||
Console.WriteLine($"UseShardingCore:" + startNew.ElapsedMilliseconds + "ms");
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
||||
DynamicShardingHelper.DynamicAppendDataSource<DefaultShardingDbContext>("c1","B", "Data Source=localhost;Initial Catalog=ShardingCoreDBXAABB;Integrated Security=True;");
|
||||
// DynamicShardingHelper.DynamicAppendDataSource<DefaultShardingDbContext>("c1","B", "Data Source=localhost;Initial Catalog=ShardingCoreDBXAABB;Integrated Security=True;");
|
||||
app.DbSeed();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace Sample.SqlServer.UnionAllMerge
|
|||
{
|
||||
public static class ShardingCoreSqlServerExtension
|
||||
{
|
||||
public static void UseSqlServer<TShardingDbContext>(this ShardingConfigOptions<TShardingDbContext> option,Action<DbContextOptionsBuilder> builderConfigure=null) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public static void UseSqlServer(this ShardingConfigOptions option,Action<DbContextOptionsBuilder> builderConfigure=null)
|
||||
{
|
||||
option.UseShardingQuery((conStr, builder) =>
|
||||
{
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 分表、分库对象确定参数用来初始化<see cref="EntityMetadata"/>时所需的信息
|
||||
/// </summary>
|
||||
public class EntityMetadataEnsureParams
|
||||
{
|
||||
public EntityMetadataEnsureParams(IEntityType entityType)
|
||||
{
|
||||
EntityType = entityType;
|
||||
|
||||
VirtualTableName = entityType.GetEntityTypeTableName();
|
||||
}
|
||||
|
||||
public IEntityType EntityType { get; }
|
||||
public string VirtualTableName { get; }
|
||||
}
|
||||
}
|
|
@ -1,19 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.EntityShardingMetadatas;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Helpers;
|
||||
|
@ -33,36 +28,30 @@ namespace ShardingCore.Bootstrappers
|
|||
/// <summary>
|
||||
/// 对象元数据初始化器
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
public class EntityMetadataInitializer<TShardingDbContext,TEntity>: IEntityMetadataInitializer where TShardingDbContext:DbContext,IShardingDbContext where TEntity:class
|
||||
public class EntityMetadataInitializer<TEntity>: IEntityMetadataInitializer where TEntity:class
|
||||
{
|
||||
private static readonly ILogger<EntityMetadataInitializer<TShardingDbContext, TEntity>> _logger=InternalLoggerFactory.CreateLogger<EntityMetadataInitializer<TShardingDbContext,TEntity>>();
|
||||
private const string QueryFilter = "QueryFilter";
|
||||
private readonly IEntityType _entityType;
|
||||
private readonly string _virtualTableName;
|
||||
private readonly Expression<Func<TEntity,bool>> _queryFilterExpression;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _shardingEntityConfigOptions;
|
||||
private readonly IVirtualDataSourceManager<TShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _virtualDataSourceRouteManager;
|
||||
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private static readonly ILogger<EntityMetadataInitializer<TEntity>> _logger=ShardingLoggerFactory.CreateLogger<EntityMetadataInitializer<TEntity>>();
|
||||
private readonly Type _shardingEntityType;
|
||||
private readonly IShardingProvider _shardingProvider;
|
||||
private readonly IShardingRouteConfigOptions _shardingRouteConfigOptions;
|
||||
private readonly IVirtualDataSourceRouteManager _virtualDataSourceRouteManager;
|
||||
private readonly ITableRouteManager _tableRouteManager;
|
||||
private readonly IEntityMetadataManager _entityMetadataManager;
|
||||
|
||||
public EntityMetadataInitializer(EntityMetadataEnsureParams entityMetadataEnsureParams,
|
||||
IShardingEntityConfigOptions<TShardingDbContext> shardingEntityConfigOptions,
|
||||
IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager,
|
||||
IVirtualDataSourceRouteManager<TShardingDbContext> virtualDataSourceRouteManager,
|
||||
IVirtualTableManager<TShardingDbContext> virtualTableManager,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager
|
||||
public EntityMetadataInitializer(
|
||||
IShardingProvider shardingProvider,
|
||||
IShardingRouteConfigOptions shardingRouteConfigOptions,
|
||||
IVirtualDataSourceRouteManager virtualDataSourceRouteManager,
|
||||
ITableRouteManager tableRouteManager,
|
||||
IEntityMetadataManager entityMetadataManager
|
||||
)
|
||||
{
|
||||
_entityType = entityMetadataEnsureParams.EntityType;
|
||||
_virtualTableName = entityMetadataEnsureParams.VirtualTableName;
|
||||
_queryFilterExpression = entityMetadataEnsureParams.EntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as Expression<Func<TEntity, bool>>;
|
||||
_shardingEntityConfigOptions = shardingEntityConfigOptions;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_shardingEntityType = typeof(TEntity);
|
||||
_shardingProvider = shardingProvider;
|
||||
_shardingRouteConfigOptions = shardingRouteConfigOptions;
|
||||
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_tableRouteManager = tableRouteManager;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -74,20 +63,18 @@ namespace ShardingCore.Bootstrappers
|
|||
/// <exception cref="ShardingCoreInvalidOperationException"></exception>
|
||||
public void Initialize()
|
||||
{
|
||||
var shardingEntityType = _entityType.ClrType;
|
||||
var entityMetadata = new EntityMetadata(shardingEntityType, _virtualTableName,typeof(TShardingDbContext),_entityType.FindPrimaryKey()?.Properties?.Select(o=>o.PropertyInfo)?.ToList()??new List<PropertyInfo>(),_queryFilterExpression);
|
||||
var entityMetadata = new EntityMetadata(_shardingEntityType);
|
||||
if (!_entityMetadataManager.AddEntityMetadata(entityMetadata))
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add entity metadata {shardingEntityType.FullName}");
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add entity metadata {_shardingEntityType.FullName}");
|
||||
//设置标签
|
||||
if (_shardingEntityConfigOptions.TryGetVirtualDataSourceRoute<TEntity>(out var virtualDataSourceRouteType))
|
||||
if (_shardingRouteConfigOptions.TryGetVirtualDataSourceRoute<TEntity>(out var virtualDataSourceRouteType))
|
||||
{
|
||||
var creatEntityMetadataDataSourceBuilder = EntityMetadataDataSourceBuilder<TEntity>.CreateEntityMetadataDataSourceBuilder(entityMetadata);
|
||||
//配置属性分库信息
|
||||
EntityMetadataHelper.Configure(creatEntityMetadataDataSourceBuilder);
|
||||
var dataSourceRoute = CreateVirtualDataSourceRoute(virtualDataSourceRouteType, entityMetadata);
|
||||
var dataSourceRoute = CreateVirtualDataSourceRoute(virtualDataSourceRouteType);
|
||||
if (dataSourceRoute is IEntityMetadataAutoBindInitializer entityMetadataAutoBindInitializer)
|
||||
{
|
||||
entityMetadataAutoBindInitializer.Initialize(entityMetadata);
|
||||
entityMetadataAutoBindInitializer.Initialize(entityMetadata,_shardingProvider);
|
||||
}
|
||||
//配置分库信息
|
||||
if(dataSourceRoute is IEntityMetadataDataSourceConfiguration<TEntity> entityMetadataDataSourceConfiguration)
|
||||
|
@ -98,19 +85,15 @@ namespace ShardingCore.Bootstrappers
|
|||
entityMetadata.CheckShardingDataSourceMetadata();
|
||||
|
||||
}
|
||||
if (_shardingEntityConfigOptions.TryGetVirtualTableRoute<TEntity>(out var virtualTableRouteType))
|
||||
if (_shardingRouteConfigOptions.TryGetVirtualTableRoute<TEntity>(out var virtualTableRouteType))
|
||||
{
|
||||
if (!typeof(TShardingDbContext).IsShardingTableDbContext())
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{typeof(TShardingDbContext)} is not impl {nameof(IShardingTableDbContext)},not support sharding table");
|
||||
var entityMetadataTableBuilder = EntityMetadataTableBuilder<TEntity>.CreateEntityMetadataTableBuilder(entityMetadata);
|
||||
//配置属性分表信息
|
||||
EntityMetadataHelper.Configure(entityMetadataTableBuilder);
|
||||
|
||||
var virtualTableRoute = CreateVirtualTableRoute(virtualTableRouteType, entityMetadata);
|
||||
var virtualTableRoute = CreateVirtualTableRoute(virtualTableRouteType);
|
||||
if (virtualTableRoute is IEntityMetadataAutoBindInitializer entityMetadataAutoBindInitializer)
|
||||
{
|
||||
entityMetadataAutoBindInitializer.Initialize(entityMetadata);
|
||||
entityMetadataAutoBindInitializer.Initialize(entityMetadata,_shardingProvider);
|
||||
}
|
||||
//配置分表信息
|
||||
if (virtualTableRoute is IEntityMetadataTableConfiguration<TEntity> createEntityMetadataTableConfiguration)
|
||||
|
@ -118,61 +101,30 @@ namespace ShardingCore.Bootstrappers
|
|||
createEntityMetadataTableConfiguration.Configure(entityMetadataTableBuilder);
|
||||
}
|
||||
//创建虚拟表
|
||||
var virtualTable = CreateVirtualTable(virtualTableRoute,entityMetadata);
|
||||
_virtualTableManager.AddVirtualTable(virtualTable);
|
||||
_tableRouteManager.AddRoute(virtualTableRoute);
|
||||
//检测校验分表分库对象元数据
|
||||
entityMetadata.CheckShardingTableMetadata();
|
||||
//添加任务
|
||||
if (virtualTableRoute is IJob routeJob && routeJob.AutoCreateTableByTime())
|
||||
if (virtualTableRoute is IJob routeJob&&routeJob.AppendJob())
|
||||
{
|
||||
var jobManager = ShardingContainer.GetService<IJobManager>();
|
||||
var jobEntry = JobEntryFactory.Create(routeJob);
|
||||
jobManager.AddJob(jobEntry);
|
||||
_shardingProvider.GetRequiredService<IJobManager>().AddJob(jobEntry);
|
||||
}
|
||||
}
|
||||
entityMetadata.CheckGenericMetadata();
|
||||
}
|
||||
|
||||
private IVirtualDataSourceRoute<TEntity> CreateVirtualDataSourceRoute(Type virtualRouteType,EntityMetadata entityMetadata)
|
||||
private IVirtualDataSourceRoute<TEntity> CreateVirtualDataSourceRoute(Type virtualRouteType)
|
||||
{
|
||||
var constructors
|
||||
= virtualRouteType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
if (constructors.Length != 1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"virtual route :[{virtualRouteType}] found more declared constructor ");
|
||||
}
|
||||
|
||||
var @params = constructors[0].GetParameters().Select(x => ShardingContainer.GetService(x.ParameterType))
|
||||
.ToArray();
|
||||
object o = Activator.CreateInstance(virtualRouteType, @params);
|
||||
return (IVirtualDataSourceRoute<TEntity>)o;
|
||||
var instance = _shardingProvider.CreateInstance(virtualRouteType);
|
||||
return (IVirtualDataSourceRoute<TEntity>)instance;
|
||||
}
|
||||
|
||||
|
||||
private IVirtualTableRoute<TEntity> CreateVirtualTableRoute(Type virtualRouteType, EntityMetadata entityMetadata)
|
||||
private IVirtualTableRoute<TEntity> CreateVirtualTableRoute(Type virtualRouteType)
|
||||
{
|
||||
var constructors
|
||||
= virtualRouteType.GetTypeInfo().DeclaredConstructors
|
||||
.Where(c => !c.IsStatic && c.IsPublic)
|
||||
.ToArray();
|
||||
|
||||
if (constructors.Length !=1)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
$"virtual route :[{virtualRouteType}] found more declared constructor ");
|
||||
}
|
||||
var @params = constructors[0].GetParameters().Select(x => ShardingContainer.GetService(x.ParameterType))
|
||||
.ToArray();
|
||||
object o = Activator.CreateInstance(virtualRouteType, @params);
|
||||
return (IVirtualTableRoute<TEntity>)o;
|
||||
}
|
||||
|
||||
private IVirtualTable<TEntity> CreateVirtualTable(IVirtualTableRoute<TEntity> virtualTableRoute,EntityMetadata entityMetadata)
|
||||
{
|
||||
return new DefaultVirtualTable<TEntity>(virtualTableRoute, entityMetadata);
|
||||
var instance = _shardingProvider.CreateInstance(virtualRouteType);
|
||||
return (IVirtualTableRoute<TEntity>)instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,13 +7,10 @@
|
|||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 主要的分表启动器
|
||||
/// 主要的分表初始化器,不再需要手动调用,<code>IShardingRuntimeContext初始化的时候会调用</code>
|
||||
/// </summary>
|
||||
public interface IShardingBootstrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
void Start();
|
||||
void AutoShardingTable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
|
||||
internal interface IShardingInitializer
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
void Initialize();
|
||||
}
|
||||
}
|
|
@ -1,13 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Jobs;
|
||||
using ShardingCore.Jobs.Abstaractions;
|
||||
using ShardingCore.Logger;
|
||||
using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
|
||||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
|
@ -19,40 +27,49 @@ namespace ShardingCore.Bootstrappers
|
|||
*/
|
||||
public class ShardingBootstrapper : IShardingBootstrapper
|
||||
{
|
||||
private readonly ILogger<ShardingBootstrapper> _logger;
|
||||
private readonly IEnumerable<IDbContextTypeCollector> _dbContextTypeCollectors;
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
private readonly IShardingProvider _shardingProvider;
|
||||
private readonly IDbContextCreator _dbContextCreator;
|
||||
|
||||
public ShardingBootstrapper(IServiceProvider serviceProvider,IEnumerable<IDbContextTypeCollector> dbContextTypeCollectors)
|
||||
public ShardingBootstrapper(IShardingProvider shardingProvider,IDbContextCreator dbContextCreator)
|
||||
{
|
||||
ShardingContainer.SetServices(serviceProvider);
|
||||
InternalLoggerFactory.DefaultFactory = serviceProvider.GetService<ILoggerFactory>();
|
||||
_logger = InternalLoggerFactory.DefaultFactory .CreateLogger<ShardingBootstrapper>();
|
||||
_dbContextTypeCollectors = dbContextTypeCollectors;
|
||||
_shardingProvider = shardingProvider;
|
||||
_dbContextCreator = dbContextCreator;
|
||||
}
|
||||
/// <summary>
|
||||
/// 启动
|
||||
/// </summary>
|
||||
public void Start()
|
||||
public void AutoShardingTable()
|
||||
{
|
||||
if (!_doOnlyOnce.IsUnDo())
|
||||
return;
|
||||
_logger.LogDebug("sharding core starting......");
|
||||
foreach (var dbContextTypeCollector in _dbContextTypeCollectors)
|
||||
{
|
||||
var instance = (IShardingDbContextBootstrapper)ShardingContainer.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(dbContextTypeCollector.ShardingDbContextType));
|
||||
_logger.LogDebug($"{dbContextTypeCollector.ShardingDbContextType} start init......");
|
||||
instance.Init();
|
||||
_logger.LogDebug($"{dbContextTypeCollector.ShardingDbContextType} complete init");
|
||||
}
|
||||
CheckRequirement();
|
||||
StartAutoShardingJob();
|
||||
}
|
||||
|
||||
var jobManager = ShardingContainer.GetService<IJobManager>();
|
||||
if (jobManager != null && jobManager.HasAnyJob())
|
||||
private void StartAutoShardingJob()
|
||||
{
|
||||
var jobRunnerService = _shardingProvider.GetRequiredService<JobRunnerService>(false);
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
Task.Factory.StartNew(async () =>
|
||||
await jobRunnerService.StartAsync();
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
private void CheckRequirement()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var scope = _shardingProvider.CreateScope())
|
||||
{
|
||||
await ShardingContainer.GetService<JobRunnerService>().StartAsync();
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
using (var dbContext = _dbContextCreator.GetShellDbContext(scope.ServiceProvider))
|
||||
{
|
||||
if (dbContext == null)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"cant get shell db context,plz override {nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"cant get shell db context,plz override {nameof(IDbContextCreator)}.{nameof(IDbContextCreator.GetShellDbContext)}",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.TrackerManagers;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/20 14:04:55
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
/// <summary>
|
||||
/// 分片具体DbContext初始化器
|
||||
/// </summary>
|
||||
public interface IShardingDbContextBootstrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
void Init();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分片具体DbContext初始化器
|
||||
/// </summary>
|
||||
public class ShardingDbContextBootstrapper<TShardingDbContext> : IShardingDbContextBootstrapper where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IVirtualDataSourceManager<TShardingDbContext> _virtualDataSourceManager;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _entityConfigOptions;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IParallelTableManager<TShardingDbContext> _parallelTableManager;
|
||||
private readonly IDataSourceInitializer<TShardingDbContext> _dataSourceInitializer;
|
||||
private readonly ITrackerManager<TShardingDbContext> _trackerManager;
|
||||
private readonly Type _shardingDbContextType;
|
||||
|
||||
public ShardingDbContextBootstrapper(
|
||||
IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager,
|
||||
IShardingEntityConfigOptions<TShardingDbContext> entityConfigOptions,
|
||||
IEntityMetadataManager<TShardingDbContext> entityMetadataManager,
|
||||
IParallelTableManager<TShardingDbContext> parallelTableManager,
|
||||
IDataSourceInitializer<TShardingDbContext> dataSourceInitializer,
|
||||
ITrackerManager<TShardingDbContext> trackerManager)
|
||||
{
|
||||
_shardingDbContextType = typeof(TShardingDbContext);
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
_entityConfigOptions = entityConfigOptions;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_parallelTableManager = parallelTableManager;
|
||||
_dataSourceInitializer = dataSourceInitializer;
|
||||
_trackerManager = trackerManager;
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
InitializeEntityMetadata();
|
||||
InitializeParallelTables();
|
||||
InitializeConfigure();
|
||||
}
|
||||
|
||||
private void InitializeEntityMetadata()
|
||||
{
|
||||
using (var serviceScope = ShardingContainer.ServiceProvider.CreateScope())
|
||||
{
|
||||
var configId = _virtualDataSourceManager.GetAllVirtualDataSources().First().ConfigId;
|
||||
using (_virtualDataSourceManager.CreateScope(configId))
|
||||
{
|
||||
//var dataSourceName = _virtualDataSource.DefaultDataSourceName;
|
||||
|
||||
using var context =
|
||||
(DbContext)serviceScope.ServiceProvider.GetService(_shardingDbContextType);
|
||||
foreach (var entity in context.Model.GetEntityTypes())
|
||||
{
|
||||
var entityType = entity.ClrType;
|
||||
|
||||
_trackerManager.AddDbContextModel(entityType,entity.FindPrimaryKey()!=null);
|
||||
//entity.GetAnnotation("")
|
||||
if (_entityConfigOptions.HasVirtualDataSourceRoute(entityType) ||
|
||||
_entityConfigOptions.HasVirtualTableRoute(entityType))
|
||||
{
|
||||
var entityMetadataInitializerType = typeof(EntityMetadataInitializer<,>).GetGenericType1(_shardingDbContextType, entityType);
|
||||
|
||||
var entityMetadataInitializer = (IEntityMetadataInitializer)ShardingContainer.CreateInstanceWithInputParams(entityMetadataInitializerType, new EntityMetadataEnsureParams(entity));
|
||||
entityMetadataInitializer.Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
//if (_shardingConfigOption.EnsureCreatedWithOutShardingTable)
|
||||
// EnsureCreated(context, dataSourceName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void InitializeParallelTables()
|
||||
{
|
||||
foreach (var parallelTableGroupNode in _entityConfigOptions.GetParallelTableGroupNodes())
|
||||
{
|
||||
var parallelTableComparerType = parallelTableGroupNode.GetEntities().FirstOrDefault(o => !_entityMetadataManager.IsShardingTable(o.Type));
|
||||
if (parallelTableComparerType != null)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{parallelTableComparerType.Type.Name} must is sharding table type");
|
||||
}
|
||||
_parallelTableManager.AddParallelTable(parallelTableGroupNode);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeConfigure()
|
||||
{
|
||||
var allVirtualDataSources = _virtualDataSourceManager.GetAllVirtualDataSources();
|
||||
foreach (var virtualDataSource in allVirtualDataSources)
|
||||
{
|
||||
var dataSources = virtualDataSource.GetDataSources();
|
||||
foreach (var dataSourceKv in dataSources)
|
||||
{
|
||||
var dataSourceName = dataSourceKv.Key;
|
||||
var connectionString = dataSourceKv.Value;
|
||||
_dataSourceInitializer.InitConfigure(virtualDataSource,dataSourceName, connectionString, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Jobs;
|
||||
using ShardingCore.Jobs.Abstaractions;
|
||||
using ShardingCore.Logger;
|
||||
using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
|
||||
namespace ShardingCore.Bootstrappers
|
||||
{
|
||||
|
||||
internal class ShardingInitializer:IShardingInitializer
|
||||
{
|
||||
private readonly ILogger<ShardingBootstrapper> _logger;
|
||||
private readonly IShardingProvider _shardingProvider;
|
||||
private readonly IShardingRouteConfigOptions _routeConfigOptions;
|
||||
private readonly IEntityMetadataManager _entityMetadataManager;
|
||||
private readonly IParallelTableManager _parallelTableManager;
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
|
||||
public ShardingInitializer(IShardingProvider shardingProvider)
|
||||
{
|
||||
_logger = ShardingLoggerFactory.DefaultFactory.CreateLogger<ShardingBootstrapper>();
|
||||
_shardingProvider = shardingProvider;
|
||||
_routeConfigOptions = shardingProvider.GetRequiredService<IShardingRouteConfigOptions>();
|
||||
_entityMetadataManager = shardingProvider.GetRequiredService<IEntityMetadataManager>();
|
||||
_parallelTableManager = shardingProvider.GetRequiredService<IParallelTableManager>();
|
||||
}
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public void Initialize()
|
||||
{
|
||||
if (!_doOnlyOnce.IsUnDo())
|
||||
return;
|
||||
_logger.LogDebug("sharding core starting......");
|
||||
|
||||
_logger.LogDebug("sharding core initialize entity metadata......");
|
||||
InitializeEntityMetadata();
|
||||
_logger.LogDebug("sharding core initialize parallel table......");
|
||||
InitializeParallelTables();
|
||||
// _logger.LogDebug("sharding core check completeness......");
|
||||
// CheckCompleteness();
|
||||
_logger.LogDebug($"sharding core complete init");
|
||||
_logger.LogDebug("sharding core running......");
|
||||
}
|
||||
|
||||
private void InitializeEntityMetadata()
|
||||
{
|
||||
var shardingEntities = _routeConfigOptions.GetShardingTableRouteTypes()
|
||||
.Concat(_routeConfigOptions.GetShardingDataSourceRouteTypes()).ToHashSet();
|
||||
foreach (var entityType in shardingEntities)
|
||||
{
|
||||
var entityMetadataInitializerType =
|
||||
typeof(EntityMetadataInitializer<>).GetGenericType0(entityType);
|
||||
|
||||
var entityMetadataInitializer =(IEntityMetadataInitializer)_shardingProvider.CreateInstance(entityMetadataInitializerType);
|
||||
entityMetadataInitializer.Initialize();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeParallelTables()
|
||||
{
|
||||
foreach (var parallelTableGroupNode in _routeConfigOptions.GetParallelTableGroupNodes())
|
||||
{
|
||||
var parallelTableComparerType = parallelTableGroupNode.GetEntities()
|
||||
.FirstOrDefault(o => !_entityMetadataManager.IsShardingTable(o.Type));
|
||||
if (parallelTableComparerType != null)
|
||||
{
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{parallelTableComparerType.Type.Name} must is sharding table type");
|
||||
}
|
||||
|
||||
_parallelTableManager.AddParallelTable(parallelTableGroupNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ namespace ShardingCore.Core
|
|||
[ExcludeFromCodeCoverage]
|
||||
private Check(){}
|
||||
/// <summary>
|
||||
/// 不能为空
|
||||
/// 不能为空
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
|
@ -28,7 +28,7 @@ namespace ShardingCore.Core
|
|||
return value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 应该为空
|
||||
/// 应该为空
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="value"></param>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading;
|
||||
|
||||
namespace ShardingCore.Core.Collections
|
||||
{
|
||||
|
||||
public class SafeReadAppendList<T>
|
||||
{
|
||||
private ImmutableList<T> _list;
|
||||
public SafeReadAppendList(IEnumerable<T> list)
|
||||
{
|
||||
_list = ImmutableList.CreateRange(list);
|
||||
}
|
||||
public SafeReadAppendList():this(new List<T>(0))
|
||||
{
|
||||
}
|
||||
|
||||
public IReadOnlyList<T> Data => _list;
|
||||
|
||||
public void Append(T value)
|
||||
{
|
||||
ImmutableList<T> original;
|
||||
ImmutableList<T> afterChange;
|
||||
do
|
||||
{
|
||||
original = _list!;
|
||||
afterChange = _list!.Add(value);
|
||||
}
|
||||
while (Interlocked.CompareExchange(ref _list, afterChange, original) != original);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -4,8 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
|
@ -20,7 +19,7 @@ namespace ShardingCore.Core.DbContextCreator
|
|||
/// Author: xjm
|
||||
/// Created: 2022/4/2 21:15:09
|
||||
/// Email: 326308290@qq.com
|
||||
public class ActivatorDbContextCreator<TShardingDbContext>: IDbContextCreator<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ActivatorDbContextCreator<TShardingDbContext>: IDbContextCreator where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly Func<ShardingDbContextOptions, DbContext> _creator;
|
||||
public ActivatorDbContextCreator()
|
||||
|
@ -34,7 +33,7 @@ namespace ShardingCore.Core.DbContextCreator
|
|||
/// <param name="shellDbContext"></param>
|
||||
/// <param name="shardingDbContextOptions"></param>
|
||||
/// <returns></returns>
|
||||
public DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions)
|
||||
public virtual DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions)
|
||||
{
|
||||
var dbContext = _creator(shardingDbContextOptions);
|
||||
if (dbContext is IShardingTableDbContext shardingTableDbContext)
|
||||
|
@ -44,5 +43,10 @@ namespace ShardingCore.Core.DbContextCreator
|
|||
_ = dbContext.Model;
|
||||
return dbContext;
|
||||
}
|
||||
|
||||
public virtual DbContext GetShellDbContext(IShardingProvider shardingProvider)
|
||||
{
|
||||
return shardingProvider.GetService<TShardingDbContext>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.DbContextCreator
|
||||
|
@ -24,12 +25,13 @@ namespace ShardingCore.Core.DbContextCreator
|
|||
/// <param name="shellDbContext">最外部的dbcontext也就是壳不具备真正的执行</param>
|
||||
/// <param name="shardingDbContextOptions">返回dbcontext的配置路由等信息</param>
|
||||
/// <returns></returns>
|
||||
public DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions);
|
||||
}
|
||||
|
||||
public interface IDbContextCreator<TShardingDbContext> : IDbContextCreator
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
DbContext CreateDbContext(DbContext shellDbContext, ShardingDbContextOptions shardingDbContextOptions);
|
||||
|
||||
/// <summary>
|
||||
/// 返回shell db context 框架如何获取db context
|
||||
/// </summary>
|
||||
/// <param name="shardingProvider"></param>
|
||||
/// <returns></returns>
|
||||
DbContext GetShellDbContext(IShardingProvider shardingProvider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.EntityMetadatas
|
||||
|
@ -10,8 +13,7 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// <summary>
|
||||
/// 默认分片对象元数据管理者实现
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
public class DefaultEntityMetadataManager<TShardingDbContext> : IEntityMetadataManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class DefaultEntityMetadataManager : IEntityMetadataManager
|
||||
{
|
||||
private readonly ConcurrentDictionary<Type, EntityMetadata> _caches =new ();
|
||||
public bool AddEntityMetadata(EntityMetadata entityMetadata)
|
||||
|
@ -72,5 +74,20 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
{
|
||||
return _caches.ContainsKey(entityType);
|
||||
}
|
||||
|
||||
public List<Type> GetAllShardingEntities()
|
||||
{
|
||||
return _caches.Keys.ToList();
|
||||
}
|
||||
|
||||
public bool TryInitModel(IEntityType efEntityType)
|
||||
{
|
||||
if (_caches.TryGetValue(efEntityType.ClrType,out var metadata))
|
||||
{
|
||||
metadata.SetEntityModel(efEntityType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Extensions.InternalExtensions;
|
||||
|
||||
namespace ShardingCore.Core.EntityMetadatas
|
||||
{
|
||||
|
@ -12,15 +16,10 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// 分表或者分库对象的元数据信息记录对象在ShardingCore框架下的一些简单的信息
|
||||
/// </summary>
|
||||
public class EntityMetadata
|
||||
{
|
||||
public EntityMetadata(Type entityType, string virtualTableName,Type shardingDbContextType, IReadOnlyList<PropertyInfo> primaryKeyProperties,LambdaExpression queryFilterExpression)
|
||||
{private const string QueryFilter = "QueryFilter";
|
||||
public EntityMetadata(Type entityType)
|
||||
{
|
||||
EntityType = entityType;
|
||||
VirtualTableName = virtualTableName;
|
||||
ShardingDbContextType = shardingDbContextType;
|
||||
PrimaryKeyProperties = primaryKeyProperties;
|
||||
QueryFilterExpression = queryFilterExpression;
|
||||
IsSingleKey= PrimaryKeyProperties.Count == 1;
|
||||
ShardingDataSourceProperties = new Dictionary<string, PropertyInfo>();
|
||||
ShardingTableProperties = new Dictionary<string, PropertyInfo>();
|
||||
}
|
||||
|
@ -28,26 +27,6 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// 分表类型 sharding entity type
|
||||
/// </summary>
|
||||
public Type EntityType { get; }
|
||||
/// <summary>
|
||||
/// 分表的原表名 original table name in db exclude tail
|
||||
/// </summary>
|
||||
public string VirtualTableName { get; }
|
||||
|
||||
public Type ShardingDbContextType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public IReadOnlyList<PropertyInfo> PrimaryKeyProperties { get; }
|
||||
/**
|
||||
* efcore query filter
|
||||
*/
|
||||
public LambdaExpression QueryFilterExpression { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否单主键
|
||||
/// </summary>
|
||||
public bool IsSingleKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否多数据源
|
||||
|
@ -91,6 +70,37 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// 分表隔离器 table sharding tail prefix
|
||||
/// </summary>
|
||||
public string TableSeparator { get; private set; } = "_";
|
||||
|
||||
/// <summary>
|
||||
/// 逻辑表名
|
||||
/// </summary>
|
||||
public string LogicTableName { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public IReadOnlyList<PropertyInfo> PrimaryKeyProperties { get; private set; }
|
||||
/**
|
||||
* efcore query filter
|
||||
*/
|
||||
public LambdaExpression QueryFilterExpression { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否单主键
|
||||
/// </summary>
|
||||
public bool IsSingleKey { get; private set; }
|
||||
|
||||
public void SetEntityModel(IEntityType dbEntityType)
|
||||
{
|
||||
LogicTableName = dbEntityType.GetEntityTypeTableName();
|
||||
QueryFilterExpression= dbEntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as LambdaExpression;
|
||||
PrimaryKeyProperties = dbEntityType.FindPrimaryKey()?.Properties?.Select(o => o.PropertyInfo)?.ToList() ??
|
||||
new List<PropertyInfo>();
|
||||
IsSingleKey=PrimaryKeyProperties.Count == 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置分库字段
|
||||
/// </summary>
|
||||
|
@ -179,7 +189,7 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// </summary>
|
||||
public void CheckGenericMetadata()
|
||||
{
|
||||
if (null == EntityType || null == PrimaryKeyProperties || null == VirtualTableName ||
|
||||
if (null == EntityType ||
|
||||
(!IsMultiTableMapping && !IsMultiDataSourceMapping))
|
||||
{
|
||||
throw new ShardingCoreException($"not found entity:{EntityType} configure");
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
namespace ShardingCore.Core.EntityMetadatas
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
|
||||
namespace ShardingCore.Core.EntityMetadatas
|
||||
{
|
||||
/// <summary>
|
||||
/// 元数据和路由绑定初始化器
|
||||
/// </summary>
|
||||
public interface IEntityMetadataAutoBindInitializer
|
||||
{
|
||||
IShardingProvider RouteShardingProvider { get; }
|
||||
/// <summary>
|
||||
/// 初始化 在启动时会被调用并且将对象元数据绑定到对应的路由上面
|
||||
/// </summary>
|
||||
/// <param name="entityMetadata"></param>
|
||||
void Initialize(EntityMetadata entityMetadata);
|
||||
/// <param name="shardingProvider"></param>
|
||||
void Initialize(EntityMetadata entityMetadata,IShardingProvider shardingProvider);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.EntityMetadatas
|
||||
|
@ -41,5 +43,9 @@ namespace ShardingCore.Core.EntityMetadatas
|
|||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
bool IsSharding(Type entityType);
|
||||
|
||||
List<Type> GetAllShardingEntities();
|
||||
|
||||
bool TryInitModel(IEntityType efEntityType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.EntityMetadatas
|
||||
{
|
||||
/// <summary>
|
||||
/// 分片 对象元数据信息管理 可以通过依赖注入获取
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
public interface IEntityMetadataManager<TShardingDbContext>: IEntityMetadataManager where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
[Obsolete("will remove")]
|
||||
public interface IShardingDataSource
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/17 13:21:04
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
[Obsolete("will remove")]
|
||||
public interface IShardingTable
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
using System;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Core.PhysicTables
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 18 December 2020 13:57:50
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 默认的物理表
|
||||
/// </summary>
|
||||
public class DefaultPhysicTable : IPhysicTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 物理表
|
||||
/// </summary>
|
||||
/// <param name="virtualTable">虚拟表</param>
|
||||
/// <param name="tail">物理表表后缀</param>
|
||||
public DefaultPhysicTable(IVirtualTable virtualTable, string tail)
|
||||
{
|
||||
VirtualTable = virtualTable;
|
||||
OriginalName = virtualTable.GetVirtualTableName();
|
||||
Tail = tail;
|
||||
EntityMetadata = VirtualTable.EntityMetadata;
|
||||
EntityType = EntityMetadata.EntityType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 元数据对象
|
||||
/// </summary>
|
||||
public EntityMetadata EntityMetadata { get; }
|
||||
/// <summary>
|
||||
/// 全表名称
|
||||
/// </summary>
|
||||
public string FullName => $"{OriginalName}{TableSeparator}{Tail}";
|
||||
/// <summary>
|
||||
/// 原始表名
|
||||
/// </summary>
|
||||
public string OriginalName { get; }
|
||||
/// <summary>
|
||||
/// 分表的表名和后置的连接器默认为下划线"_" 可以为空
|
||||
/// </summary>
|
||||
public string TableSeparator => EntityMetadata.TableSeparator;
|
||||
/// <summary>
|
||||
/// 分表后缀
|
||||
/// </summary>
|
||||
public string Tail { get; }
|
||||
/// <summary>
|
||||
/// 类型对象
|
||||
/// </summary>
|
||||
public Type EntityType { get; }
|
||||
/// <summary>
|
||||
/// 所属虚拟表
|
||||
/// </summary>
|
||||
public IVirtualTable VirtualTable { get; }
|
||||
protected bool Equals(DefaultPhysicTable other)
|
||||
{
|
||||
return OriginalName == other.OriginalName && Tail == other.Tail && Equals(EntityType, other.EntityType);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((DefaultPhysicTable)obj);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(OriginalName, Tail, VirtualTable);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (OriginalName != null ? OriginalName.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Tail != null ? Tail.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (VirtualTable != null ? VirtualTable.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
using System;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 18 December 2020 13:54:46
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
namespace ShardingCore.Core.PhysicTables
|
||||
{
|
||||
/// <summary>
|
||||
/// 物理表接口
|
||||
/// </summary>
|
||||
public interface IPhysicTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象信息
|
||||
/// </summary>
|
||||
EntityMetadata EntityMetadata { get; }
|
||||
/// <summary>
|
||||
/// 表全称
|
||||
/// </summary>
|
||||
string FullName { get; }
|
||||
/// <summary>
|
||||
/// 原表名称
|
||||
/// </summary>
|
||||
string OriginalName { get; }
|
||||
/// <summary>
|
||||
/// 尾巴前缀 tail prefix
|
||||
/// </summary>
|
||||
string TableSeparator { get; }
|
||||
/// <summary>
|
||||
/// 尾巴
|
||||
/// </summary>
|
||||
string Tail { get; }
|
||||
/// <summary>
|
||||
/// 映射类类型
|
||||
/// </summary>
|
||||
Type EntityType { get; }
|
||||
/// <summary>
|
||||
/// 所属虚拟表
|
||||
/// </summary>
|
||||
IVirtualTable VirtualTable { get; }
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
|
||||
namespace ShardingCore.Core.QueryRouteManagers.Abstractions
|
||||
{
|
||||
|
@ -15,7 +16,7 @@ namespace ShardingCore.Core.QueryRouteManagers.Abstractions
|
|||
/// </summary>
|
||||
public interface ITableRouteAssert
|
||||
{
|
||||
void Assert(List<IPhysicTable> allPhysicTables, List<IPhysicTable> resultPhysicTables);
|
||||
void Assert(DataSourceRouteResult dataSourceRouteResult,List<string> tails, List<TableRouteUnit> shardingRouteUnits);
|
||||
}
|
||||
|
||||
public interface ITableRouteAssert<T> : ITableRouteAssert where T : class
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.QueryTrackers;
|
||||
using ShardingCore.Core.ShardingPage.Abstractions;
|
||||
using ShardingCore.Core.TrackerManagers;
|
||||
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.RuntimeContexts
|
||||
{
|
||||
|
||||
public interface IShardingRuntimeContext
|
||||
{
|
||||
IShardingCompilerExecutor GetShardingCompilerExecutor();
|
||||
IShardingReadWriteManager GetShardingReadWriteManager();
|
||||
ITrackerManager GetTrackerManager();
|
||||
IParallelTableManager GetParallelTableManager();
|
||||
IDbContextCreator GetDbContextCreator();
|
||||
IEntityMetadataManager GetEntityMetadataManager();
|
||||
// IVirtualDataSourceManager GetVirtualDataSourceManager();
|
||||
IVirtualDataSource GetVirtualDataSource();
|
||||
ITableRouteManager GetTableRouteManager();
|
||||
IRouteTailFactory GetRouteTailFactory();
|
||||
IQueryTracker GetQueryTracker();
|
||||
IUnionAllMergeManager GetUnionAllMergeManager();
|
||||
IShardingPageManager GetShardingPageManager();
|
||||
IDataSourceInitializer GetDataSourceInitializer();
|
||||
|
||||
void GetOrCreateShardingRuntimeModel(DbContext dbContext);
|
||||
|
||||
void UseLogfactory(ILoggerFactory loggerFactory);
|
||||
|
||||
void UseApplicationServiceProvider(IServiceProvider applicationServiceProvider);
|
||||
void Initialize();
|
||||
void AutoShardingTable();
|
||||
object GetService(Type serviceType);
|
||||
TService GetService<TService>();
|
||||
object GetRequiredService(Type serviceType);
|
||||
TService GetRequiredService<TService>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.Bootstrappers;
|
||||
using ShardingCore.Core.DbContextCreator;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.QueryTrackers;
|
||||
using ShardingCore.Core.ShardingPage.Abstractions;
|
||||
using ShardingCore.Core.TrackerManagers;
|
||||
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Logger;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.RuntimeContexts
|
||||
{
|
||||
public sealed class ShardingRuntimeContext:IShardingRuntimeContext
|
||||
{
|
||||
private bool isInited = false;
|
||||
private object INIT_LOCK = new object();
|
||||
private bool isInitModeled = false;
|
||||
private object INIT_MODEL = new object();
|
||||
private IServiceCollection _serviceMap = new ServiceCollection();
|
||||
|
||||
private IServiceProvider _serviceProvider;
|
||||
private IServiceProvider _applicationServiceProvider;
|
||||
|
||||
public void AddServiceConfig(Action<IServiceCollection> configure)
|
||||
{
|
||||
CheckIfBuild();
|
||||
configure(_serviceMap);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (isInited)
|
||||
return;
|
||||
|
||||
lock (INIT_LOCK)
|
||||
{
|
||||
if (isInited)
|
||||
return;
|
||||
isInited = true;
|
||||
_serviceProvider = _serviceMap.BuildServiceProvider();
|
||||
_serviceProvider.GetRequiredService<IShardingInitializer>().Initialize();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void AutoShardingTable()
|
||||
{
|
||||
GetRequiredService<IShardingBootstrapper>().AutoShardingTable();
|
||||
}
|
||||
|
||||
public IShardingCompilerExecutor GetShardingCompilerExecutor()
|
||||
{
|
||||
return GetRequiredService<IShardingCompilerExecutor>();
|
||||
}
|
||||
|
||||
public IShardingReadWriteManager GetShardingReadWriteManager()
|
||||
{
|
||||
return GetRequiredService<IShardingReadWriteManager>();
|
||||
}
|
||||
|
||||
public ITrackerManager GetTrackerManager()
|
||||
{
|
||||
return GetRequiredService<ITrackerManager>();
|
||||
}
|
||||
|
||||
public IParallelTableManager GetParallelTableManager()
|
||||
{
|
||||
return GetRequiredService<IParallelTableManager>();
|
||||
}
|
||||
|
||||
public IDbContextCreator GetDbContextCreator()
|
||||
{
|
||||
return GetRequiredService<IDbContextCreator>();
|
||||
}
|
||||
|
||||
public IEntityMetadataManager GetEntityMetadataManager()
|
||||
{
|
||||
return GetRequiredService<IEntityMetadataManager>();
|
||||
}
|
||||
|
||||
public IVirtualDataSource GetVirtualDataSource()
|
||||
{
|
||||
return GetRequiredService<IVirtualDataSource>();
|
||||
}
|
||||
|
||||
public ITableRouteManager GetTableRouteManager()
|
||||
{
|
||||
return GetRequiredService<ITableRouteManager>();
|
||||
}
|
||||
|
||||
public IRouteTailFactory GetRouteTailFactory()
|
||||
{
|
||||
return GetRequiredService<IRouteTailFactory>();
|
||||
}
|
||||
|
||||
public IQueryTracker GetQueryTracker()
|
||||
{
|
||||
return GetRequiredService<IQueryTracker>();
|
||||
}
|
||||
|
||||
public IUnionAllMergeManager GetUnionAllMergeManager()
|
||||
{
|
||||
return GetRequiredService<IUnionAllMergeManager>();
|
||||
}
|
||||
|
||||
public IShardingPageManager GetShardingPageManager()
|
||||
{
|
||||
return GetRequiredService<IShardingPageManager>();
|
||||
}
|
||||
|
||||
public IDataSourceInitializer GetDataSourceInitializer()
|
||||
{
|
||||
return GetRequiredService<IDataSourceInitializer>();
|
||||
}
|
||||
|
||||
public void GetOrCreateShardingRuntimeModel(DbContext dbContext)
|
||||
{
|
||||
if (isInitModeled) return;
|
||||
lock (INIT_MODEL)
|
||||
{
|
||||
if(isInitModeled) return;
|
||||
isInitModeled = true;
|
||||
var entityMetadataManager = GetService<IEntityMetadataManager>();
|
||||
var entityTypes = dbContext.Model.GetEntityTypes();
|
||||
foreach (var entityType in entityTypes)
|
||||
{
|
||||
entityMetadataManager.TryInitModel(entityType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UseLogfactory(ILoggerFactory loggerFactory)
|
||||
{
|
||||
ShardingLoggerFactory.DefaultFactory = loggerFactory;
|
||||
}
|
||||
|
||||
public void UseApplicationServiceProvider(IServiceProvider applicationServiceProvider)
|
||||
{
|
||||
_applicationServiceProvider = applicationServiceProvider;
|
||||
}
|
||||
|
||||
private void CheckIfBuild()
|
||||
{
|
||||
if (isInited)
|
||||
throw new InvalidOperationException("sharding runtime already build");
|
||||
}
|
||||
private void CheckIfNotBuild()
|
||||
{
|
||||
if (!isInited)
|
||||
throw new InvalidOperationException("sharding runtime not init");
|
||||
}
|
||||
|
||||
public object GetService(Type serviceType)
|
||||
{
|
||||
CheckIfNotBuild();
|
||||
return _serviceProvider.GetService(serviceType);
|
||||
}
|
||||
|
||||
public TService GetService<TService>()
|
||||
{
|
||||
CheckIfNotBuild();
|
||||
return _serviceProvider.GetService<TService>();
|
||||
}
|
||||
|
||||
public object GetRequiredService(Type serviceType)
|
||||
{
|
||||
CheckIfNotBuild();
|
||||
return _serviceProvider.GetRequiredService(serviceType);
|
||||
}
|
||||
|
||||
public TService GetRequiredService<TService>()
|
||||
{
|
||||
CheckIfNotBuild();
|
||||
return _serviceProvider.GetRequiredService<TService>();
|
||||
}
|
||||
public IShardingRouteManager GetShardingRouteManager()
|
||||
{
|
||||
return GetRequiredService<IShardingRouteManager>();
|
||||
}
|
||||
//
|
||||
// public IShardingRouteConfigOptions<TShardingDbContext> GetRequiredShardingEntityConfigOption<TShardingDbContext>()
|
||||
// where TShardingDbContext : DbContext, IShardingDbContext
|
||||
// {
|
||||
// return (IShardingRouteConfigOptions<TShardingDbContext>)GetRequiredShardingEntityConfigOption(typeof(TShardingDbContext));
|
||||
// }
|
||||
// public IShardingRouteConfigOptions GetRequiredShardingEntityConfigOption(Type shardingDbContextType)
|
||||
// {
|
||||
// return (IShardingRouteConfigOptions)GetService(typeof(IShardingRouteConfigOptions<>).GetGenericType0(shardingDbContextType));
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core.ServiceProviders
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 默认的分片服务提供者
|
||||
/// </summary>
|
||||
public interface IShardingProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 优先通过ShardingCore的IServiceProvider获取
|
||||
/// 没有再通过ApplicationServiceProvider获取
|
||||
/// </summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <param name="tryApplicationServiceProvider">是否尝试通过ApplicationServiceProvider获取</param>
|
||||
/// <returns></returns>
|
||||
object GetService(Type serviceType,bool tryApplicationServiceProvider=true);
|
||||
|
||||
/// <summary>
|
||||
/// 优先通过ShardingCore的IServiceProvider获取
|
||||
/// 没有再通过ApplicationServiceProvider获取
|
||||
/// </summary>
|
||||
/// <param name="tryApplicationServiceProvider">是否尝试通过ApplicationServiceProvider获取</param>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <returns></returns>
|
||||
TService GetService<TService>(bool tryApplicationServiceProvider=true);
|
||||
|
||||
/// <summary>
|
||||
/// 优先通过ShardingCore的IServiceProvider获取
|
||||
/// 没有再通过ApplicationServiceProvider获取
|
||||
/// </summary>
|
||||
/// <param name="serviceType"></param>
|
||||
/// <param name="tryApplicationServiceProvider">是否尝试通过ApplicationServiceProvider获取</param>
|
||||
/// <returns></returns>
|
||||
object GetRequiredService(Type serviceType,bool tryApplicationServiceProvider=true);
|
||||
/// <summary>
|
||||
///
|
||||
/// 优先通过ShardingCore的IServiceProvider获取
|
||||
/// 没有再通过ApplicationServiceProvider获取
|
||||
/// </summary>
|
||||
/// <param name="tryApplicationServiceProvider">是否尝试通过ApplicationServiceProvider获取</param>
|
||||
/// <typeparam name="TService"></typeparam>
|
||||
/// <returns></returns>
|
||||
TService GetRequiredService<TService>(bool tryApplicationServiceProvider=true);
|
||||
|
||||
IShardingScope CreateScope();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core.ServiceProviders
|
||||
{
|
||||
public interface IShardingScope : IDisposable
|
||||
{
|
||||
IShardingProvider ServiceProvider { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ShardingCore.Core.ServiceProviders
|
||||
{
|
||||
|
||||
public class ShardingProvider:IShardingProvider
|
||||
{
|
||||
private readonly IServiceProvider _internalServiceProvider;
|
||||
private readonly IServiceProvider _applicationServiceProvider;
|
||||
|
||||
public ShardingProvider(IServiceProvider internalServiceProvider,IServiceProvider applicationServiceProvider)
|
||||
{
|
||||
_internalServiceProvider = internalServiceProvider;
|
||||
_applicationServiceProvider = applicationServiceProvider;
|
||||
}
|
||||
public object GetService(Type serviceType,bool tryApplicationServiceProvider=true)
|
||||
{
|
||||
var service = _internalServiceProvider?.GetService(serviceType);
|
||||
if (tryApplicationServiceProvider&&service == null)
|
||||
{
|
||||
service= _applicationServiceProvider?.GetService(serviceType);
|
||||
}
|
||||
return service;
|
||||
}
|
||||
public TService GetService<TService>(bool tryApplicationServiceProvider=true)
|
||||
{
|
||||
return (TService)GetService(typeof(TService),tryApplicationServiceProvider);
|
||||
}
|
||||
|
||||
public object GetRequiredService(Type serviceType,bool tryApplicationServiceProvider=true)
|
||||
{
|
||||
var service = GetService(serviceType,tryApplicationServiceProvider);
|
||||
if (service == null)
|
||||
{
|
||||
throw new ArgumentNullException($"cant unable resolve service:[{serviceType}]");
|
||||
}
|
||||
|
||||
return service;
|
||||
}
|
||||
public TService GetRequiredService<TService>(bool tryApplicationServiceProvider=true)
|
||||
{
|
||||
return (TService)GetRequiredService(typeof(TService),tryApplicationServiceProvider);
|
||||
}
|
||||
|
||||
public IShardingScope CreateScope()
|
||||
{
|
||||
return new ShardingScope(_internalServiceProvider.CreateScope(), _applicationServiceProvider.CreateScope());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ShardingCore.Core.ServiceProviders
|
||||
{
|
||||
|
||||
public class ShardingScope:IShardingScope
|
||||
{
|
||||
private readonly IServiceScope _internalServiceScope;
|
||||
private readonly IServiceScope _applicationServiceScope;
|
||||
private readonly IShardingProvider _shardingProvider;
|
||||
|
||||
public ShardingScope(IServiceScope internalServiceScope,IServiceScope applicationServiceScope)
|
||||
{
|
||||
_internalServiceScope = internalServiceScope;
|
||||
_applicationServiceScope = applicationServiceScope;
|
||||
_shardingProvider = new ShardingProvider(_internalServiceScope.ServiceProvider,
|
||||
_applicationServiceScope.ServiceProvider);
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
_applicationServiceScope?.Dispose();
|
||||
_internalServiceScope?.Dispose();
|
||||
}
|
||||
|
||||
public IShardingProvider ServiceProvider =>_shardingProvider;
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations.Abstractions
|
||||
{
|
||||
public interface IShardingConfigurationOptions<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
public void AddShardingGlobalConfigOptions(ShardingConfigOptions<TShardingDbContext> shardingConfigOptions);
|
||||
|
||||
public ShardingConfigOptions<TShardingDbContext>[] GetAllShardingGlobalConfigOptions();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations.Abstractions
|
||||
{
|
||||
public interface IShardingEntityConfigOptions<TShardingDbContext> : IShardingEntityConfigOptions where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 添加分库路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute;
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute;
|
||||
}
|
||||
}
|
|
@ -8,78 +8,99 @@ using System.Data.Common;
|
|||
|
||||
namespace ShardingCore.Core.ShardingConfigurations.Abstractions
|
||||
{
|
||||
public interface IShardingEntityConfigOptions
|
||||
public interface IShardingRouteConfigOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
bool? CreateShardingTableOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 是否在启动时创建数据库
|
||||
/// </summary>
|
||||
public bool? CreateDataBaseOnlyOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 当查询遇到没有路由被命中时是否抛出错误
|
||||
/// </summary>
|
||||
bool ThrowIfQueryRouteNotMatch { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// 如果数据库不存在就创建并且创建表除了分表的
|
||||
// /// </summary>
|
||||
// bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 是否需要在启动时创建分表
|
||||
// /// </summary>
|
||||
// bool? CreateShardingTableOnStart { get; set; }
|
||||
// /// <summary>
|
||||
// /// 是否在启动时创建数据库
|
||||
// /// </summary>
|
||||
// public bool? CreateDataBaseOnlyOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
bool? IgnoreCreateTableError { get; set; }
|
||||
///// <summary>
|
||||
///// 是否启用分表路由编译缓存(默认只缓存单个操作的也就是<![CDATA[=,>,>=,<,<=]]>)
|
||||
///// default cache single filter route expression, <![CDATA[=,>,>=,<,<=]]> with sharding property
|
||||
///// </summary>
|
||||
//bool? EnableTableRouteCompileCache { get; set; }
|
||||
///// <summary>
|
||||
///// 是否启用分库路由编译缓存(默认只缓存单个操作的也就是<![CDATA[=,>,>=,<,<=]]>)
|
||||
///// default cache single filter route expression, <![CDATA[=,>,>=,<,<=]]> with sharding property
|
||||
///// </summary>
|
||||
//bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
|
||||
// ///// <summary>
|
||||
// ///// 是否启用分表路由编译缓存(默认只缓存单个操作的也就是<![CDATA[=,>,>=,<,<=]]>)
|
||||
// ///// default cache single filter route expression, <![CDATA[=,>,>=,<,<=]]> with sharding property
|
||||
// ///// </summary>
|
||||
// //bool? EnableTableRouteCompileCache { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 是否启用分库路由编译缓存(默认只缓存单个操作的也就是<![CDATA[=,>,>=,<,<=]]>)
|
||||
// ///// default cache single filter route expression, <![CDATA[=,>,>=,<,<=]]> with sharding property
|
||||
// ///// </summary>
|
||||
// //bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
/// <summary>
|
||||
/// 添加分库路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute;
|
||||
|
||||
/// <summary>
|
||||
/// 添加分库路由
|
||||
/// </summary>
|
||||
/// <param name="routeType"></param>
|
||||
void AddShardingDataSourceRoute(Type routeType);
|
||||
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute;
|
||||
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <param name="routeType"></param>
|
||||
void AddShardingTableRoute(Type routeType);
|
||||
|
||||
/// <summary>
|
||||
/// 是否有虚拟表路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
bool HasVirtualTableRoute(Type entityType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
Type GetVirtualTableRouteType(Type entityType);
|
||||
|
||||
/// <summary>
|
||||
/// 是否有虚拟库路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
bool HasVirtualDataSourceRoute(Type entityType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟库路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
Type GetVirtualDataSourceRouteType(Type entityType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的分表路由类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ISet<Type> GetShardingTableRouteTypes();
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的分库路由类型
|
||||
/// </summary>
|
||||
|
@ -90,32 +111,26 @@ namespace ShardingCore.Core.ShardingConfigurations.Abstractions
|
|||
/// 平行表
|
||||
/// </summary>
|
||||
bool AddParallelTableGroupNode(ParallelTableGroupNode parallelTableGroupNode);
|
||||
|
||||
/// <summary>
|
||||
/// 获取平行表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ISet<ParallelTableGroupNode> GetParallelTableGroupNodes();
|
||||
/// <summary>
|
||||
/// DbContext如何通过现有connection创建
|
||||
/// </summary>
|
||||
Action<DbConnection, DbContextOptionsBuilder> ConnectionConfigure { get; }
|
||||
/// <summary>
|
||||
/// DbContext如何通过连接字符串创建
|
||||
/// </summary>
|
||||
Action<string, DbContextOptionsBuilder> ConnectionStringConfigure { get; }
|
||||
Action<DbContextOptionsBuilder> ExecutorDbContextConfigure { get; }
|
||||
Action<DbContextOptionsBuilder> ShellDbContextConfigure { get; }
|
||||
// /// <summary>
|
||||
// /// DbContext如何通过现有connection创建
|
||||
// /// </summary>
|
||||
// Action<DbConnection, DbContextOptionsBuilder> ConnectionConfigure { get; }
|
||||
// /// <summary>
|
||||
// /// DbContext如何通过连接字符串创建
|
||||
// /// </summary>
|
||||
// Action<string, DbContextOptionsBuilder> ConnectionStringConfigure { get; }
|
||||
// Action<DbContextOptionsBuilder> ExecutorDbContextConfigure { get; }
|
||||
// Action<DbContextOptionsBuilder> ShellDbContextConfigure { get; }
|
||||
//
|
||||
// void UseExecutorDbContextConfigure(Action<DbContextOptionsBuilder> executorDbContextConfigure);
|
||||
// void UseShellDbContextConfigure(Action<DbContextOptionsBuilder> shellDbContextConfigure);
|
||||
|
||||
/// <summary>
|
||||
/// DbContext如何通过连接字符串创建
|
||||
/// </summary>
|
||||
public void UseShardingQuery(Action<string, DbContextOptionsBuilder> queryConfigure);
|
||||
/// <summary>
|
||||
/// DbContext如何通过现有connection创建
|
||||
/// </summary>
|
||||
public void UseShardingTransaction(Action<DbConnection, DbContextOptionsBuilder> transactionConfigure);
|
||||
|
||||
void UseExecutorDbContextConfigure(Action<DbContextOptionsBuilder> executorDbContextConfigure);
|
||||
void UseShellDbContextConfigure(Action<DbContextOptionsBuilder> shellDbContextConfigure);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.DIExtensions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
|
||||
{
|
||||
public class ShardingConfigBuilder<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> ShardingCoreConfigBuilder { get; }
|
||||
|
||||
public ShardingConfigBuilder(ShardingCoreConfigBuilder<TShardingDbContext> shardingCoreConfigBuilder)
|
||||
{
|
||||
ShardingCoreConfigBuilder = shardingCoreConfigBuilder;
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加一个分片配置 必填<code>ConfigId</code>和<code>AddDefaultDataSource(string dataSourceName, string connectionString)</code>
|
||||
/// 如果全局未配置 必须配置<code>UseShardingQuery</code>和<code>UseShardingQuery</code>
|
||||
/// </summary>
|
||||
/// <param name="shardingGlobalConfigOptionsConfigure"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
/// <exception cref="ShardingCoreConfigException"></exception>
|
||||
/// <exception cref="ArgumentException"></exception>
|
||||
public ShardingConfigBuilder<TShardingDbContext> AddConfig(Action<ShardingConfigOptions<TShardingDbContext>> shardingGlobalConfigOptionsConfigure)
|
||||
{
|
||||
var shardingGlobalConfigOptions = new ShardingConfigOptions<TShardingDbContext>();
|
||||
shardingGlobalConfigOptionsConfigure?.Invoke(shardingGlobalConfigOptions);
|
||||
if (string.IsNullOrWhiteSpace(shardingGlobalConfigOptions.ConfigId))
|
||||
throw new ArgumentNullException(nameof(shardingGlobalConfigOptions.ConfigId));
|
||||
if (string.IsNullOrWhiteSpace(shardingGlobalConfigOptions.DefaultDataSourceName))
|
||||
throw new ArgumentNullException(
|
||||
$"{nameof(shardingGlobalConfigOptions.DefaultDataSourceName)} plz call {nameof(ShardingConfigOptions<TShardingDbContext>.AddDefaultDataSource)}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(shardingGlobalConfigOptions.DefaultConnectionString))
|
||||
throw new ArgumentNullException(
|
||||
$"{nameof(shardingGlobalConfigOptions.DefaultConnectionString)} plz call {nameof(ShardingConfigOptions<TShardingDbContext>.AddDefaultDataSource)}");
|
||||
|
||||
if (shardingGlobalConfigOptions.ConnectionStringConfigure is null&& ShardingCoreConfigBuilder.ShardingEntityConfigOptions.ConnectionStringConfigure is null)
|
||||
throw new ArgumentNullException($"plz call {nameof(shardingGlobalConfigOptions.UseShardingQuery)}");
|
||||
if (shardingGlobalConfigOptions.ConnectionConfigure is null && ShardingCoreConfigBuilder.ShardingEntityConfigOptions.ConnectionConfigure is null)
|
||||
throw new ArgumentNullException(
|
||||
$"plz call {nameof(shardingGlobalConfigOptions.UseShardingTransaction)}");
|
||||
|
||||
if (shardingGlobalConfigOptions.ReplaceShardingComparerFactory == null)
|
||||
{
|
||||
throw new ShardingCoreConfigException($"{nameof(shardingGlobalConfigOptions.ReplaceShardingComparerFactory)} is null");
|
||||
}
|
||||
if (shardingGlobalConfigOptions.MaxQueryConnectionsLimit <= 0)
|
||||
throw new ArgumentException(
|
||||
$"{nameof(shardingGlobalConfigOptions.MaxQueryConnectionsLimit)} should greater than and equal 1");
|
||||
ShardingCoreConfigBuilder.ShardingConfigOptions.Add(shardingGlobalConfigOptions);
|
||||
return this;
|
||||
}
|
||||
/// <summary>
|
||||
/// 单配置确认
|
||||
/// </summary>
|
||||
/// <param name="configurationStrategy"></param>
|
||||
/// <returns></returns>
|
||||
public IServiceCollection EnsureConfig(ShardingConfigurationStrategyEnum configurationStrategy = ShardingConfigurationStrategyEnum.ThrowIfNull)
|
||||
{
|
||||
return DoEnsureConfig(false,false, configurationStrategy);
|
||||
}
|
||||
/// <summary>
|
||||
/// 单配置确认 自动初始化不需要在手动<code>IShardingBootstrapper.Start()</code>
|
||||
/// </summary>
|
||||
/// <param name="configurationStrategy"></param>
|
||||
/// <returns></returns>
|
||||
public IServiceCollection EnsureConfigWithAutoStart(ShardingConfigurationStrategyEnum configurationStrategy = ShardingConfigurationStrategyEnum.ThrowIfNull)
|
||||
{
|
||||
return DoEnsureConfig(false,true, configurationStrategy);
|
||||
}
|
||||
/// <summary>
|
||||
/// 多配置确认
|
||||
/// </summary>
|
||||
/// <param name="configurationStrategy"></param>
|
||||
/// <returns></returns>
|
||||
public IServiceCollection EnsureMultiConfig(ShardingConfigurationStrategyEnum configurationStrategy= ShardingConfigurationStrategyEnum.ThrowIfNull)
|
||||
{
|
||||
return DoEnsureConfig(true,false, configurationStrategy);
|
||||
}
|
||||
/// <summary>
|
||||
/// 多配置确认 自动初始化不需要在手动<code>IShardingBootstrapper.Start()</code>
|
||||
/// </summary>
|
||||
/// <param name="configurationStrategy"></param>
|
||||
/// <returns></returns>
|
||||
public IServiceCollection EnsureMultiConfigWithAutoStart(ShardingConfigurationStrategyEnum configurationStrategy= ShardingConfigurationStrategyEnum.ThrowIfNull)
|
||||
{
|
||||
return DoEnsureConfig(true,true, configurationStrategy);
|
||||
}
|
||||
|
||||
private IServiceCollection DoEnsureConfig(bool isMultiConfig,
|
||||
bool autoStart,
|
||||
ShardingConfigurationStrategyEnum configurationStrategy)
|
||||
{
|
||||
if (ShardingCoreConfigBuilder.ShardingConfigOptions.IsEmpty())
|
||||
throw new ArgumentException($"plz call {nameof(AddConfig)} at least once ");
|
||||
if (!isMultiConfig)
|
||||
{
|
||||
if (ShardingCoreConfigBuilder.ShardingConfigOptions.Count > 1)
|
||||
{
|
||||
throw new ArgumentException($"plz call {nameof(AddConfig)} at most once ");
|
||||
}
|
||||
}
|
||||
|
||||
var services = ShardingCoreConfigBuilder.Services;
|
||||
services.AddSingleton<IDbContextTypeCollector>(sp => new DbContextTypeCollector<TShardingDbContext>());
|
||||
services.AddSingleton<IShardingEntityConfigOptions<TShardingDbContext>>(sp => ShardingCoreConfigBuilder.ShardingEntityConfigOptions);
|
||||
services.AddSingleton(sp => ShardingCoreConfigBuilder.ShardingEntityConfigOptions);
|
||||
|
||||
services.AddSingleton(sp => CreateShardingConfigurationOptions(isMultiConfig, configurationStrategy));
|
||||
services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
|
||||
if (autoStart)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
services.AddInternalShardingCore<TShardingDbContext>();
|
||||
return services;
|
||||
}
|
||||
|
||||
private IShardingConfigurationOptions<TShardingDbContext> CreateShardingConfigurationOptions(bool isMultiConfig,
|
||||
ShardingConfigurationStrategyEnum configurationStrategy)
|
||||
{
|
||||
IShardingConfigurationOptions<TShardingDbContext> shardingConfigurationOptions;
|
||||
if (!isMultiConfig)
|
||||
{
|
||||
shardingConfigurationOptions = new ShardingSingleConfigurationOptions<TShardingDbContext>
|
||||
{
|
||||
ShardingConfigurationStrategy = configurationStrategy
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
shardingConfigurationOptions = new ShardingMultiConfigurationOptions<TShardingDbContext>
|
||||
{
|
||||
ShardingConfigurationStrategy = configurationStrategy
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var configOptions in ShardingCoreConfigBuilder
|
||||
.ShardingConfigOptions)
|
||||
{
|
||||
shardingConfigurationOptions.AddShardingGlobalConfigOptions(configOptions);
|
||||
}
|
||||
|
||||
return shardingConfigurationOptions;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.ShardingConfigurations.ConfigBuilders;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Core.RuntimeContexts;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
|
||||
namespace ShardingCore.DIExtensions
|
||||
namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
|
@ -20,114 +15,66 @@ namespace ShardingCore.DIExtensions
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingCoreConfigBuilder<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ShardingCoreConfigBuilder<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
public IServiceCollection Services { get; }
|
||||
private readonly IServiceCollection _services;
|
||||
|
||||
|
||||
public List<ShardingConfigOptions<TShardingDbContext>> ShardingConfigOptions { get; }
|
||||
public ShardingEntityConfigOptions<TShardingDbContext> ShardingEntityConfigOptions { get; }
|
||||
|
||||
private readonly ShardingRuntimeBuilder<TShardingDbContext> _shardingRuntimeBuilder;
|
||||
|
||||
public ShardingCoreConfigBuilder(IServiceCollection services)
|
||||
{
|
||||
Services = services;
|
||||
ShardingConfigOptions = new List<ShardingConfigOptions<TShardingDbContext>>();
|
||||
ShardingEntityConfigOptions = new ShardingEntityConfigOptions<TShardingDbContext>();
|
||||
_services = services;
|
||||
_shardingRuntimeBuilder = new ShardingRuntimeBuilder<TShardingDbContext>();
|
||||
}
|
||||
|
||||
public ShardingConfigBuilder<TShardingDbContext> AddEntityConfig(Action<ShardingEntityConfigOptions<TShardingDbContext>> entityConfigure)
|
||||
[Obsolete("plz use UseRouteConfig")]
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> AddEntityConfig(Action<IShardingRouteConfigOptions> entityConfigure)
|
||||
{
|
||||
entityConfigure?.Invoke(ShardingEntityConfigOptions);
|
||||
return new ShardingConfigBuilder<TShardingDbContext>(this);
|
||||
_shardingRuntimeBuilder.UseRouteConfig(entityConfigure);
|
||||
return this;
|
||||
}
|
||||
//public ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> AddDefaultDataSource(string dataSourceName, string connectionString)
|
||||
//{
|
||||
// if (!string.IsNullOrWhiteSpace(defaultDataSourceName) || !string.IsNullOrWhiteSpace(defaultConnectionString))
|
||||
// throw new ShardingCoreInvalidOperationException($"{nameof(AddDefaultDataSource)}-{dataSourceName}");
|
||||
// this.defaultDataSourceName = dataSourceName;
|
||||
// this.defaultConnectionString = connectionString;
|
||||
// return this;
|
||||
//}
|
||||
|
||||
//public ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> AddDataSource(string dataSourceName, string connectionString)
|
||||
//{
|
||||
// if (_dataSources.ContainsKey(dataSourceName))
|
||||
// throw new ShardingCoreInvalidOperationException($"{nameof(AddDataSource)}-{dataSourceName} repeat");
|
||||
// _dataSources.Add(dataSourceName, connectionString);
|
||||
// return this;
|
||||
//}
|
||||
}
|
||||
|
||||
public class ShardingCoreBeginOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
public bool? CreateShardingTableOnStart { get; set; }
|
||||
///// <summary>
|
||||
///// 是否自动追踪实体
|
||||
///// 譬如本次查询涉及到a1,a2,a3这三张表,会创建3个dbcontext进行查询,如果AutoTrackEntity=false那么针对被创建的dbcontext不会有任何变化,还是以追踪的形式查询
|
||||
///// 因为会同时创建3个dbcontext所以针对跨表查询完成后dbcontext会被回收,但是查询还是按原先的行为查询,所以如果不启用建议在查询的时候使用notracking
|
||||
///// 如果AutoTrackEntity=true,那么被创建的三个dbcontext还是以原先的表现行为进行查询,在查询完成后会再次各自创建对应的dbcontext进行对象的追踪
|
||||
///// </summary>
|
||||
//public bool AutoTrackEntity { get; set; }
|
||||
/// <summary>
|
||||
/// 当查询遇到没有路由被命中时是否抛出错误
|
||||
/// </summary>
|
||||
public bool ThrowIfQueryRouteNotMatch { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
public bool? IgnoreCreateTableError { get; set; } = true;
|
||||
public int MaxQueryConnectionsLimit { get; set; } = Environment.ProcessorCount;
|
||||
public ConnectionModeEnum ConnectionMode { get; set; } = ConnectionModeEnum.SYSTEM_AUTO;
|
||||
public bool? EnableTableRouteCompileCache { get; set; }
|
||||
public bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
|
||||
private readonly ISet<Type> _createTableEntities = new HashSet<Type>();
|
||||
|
||||
public void AddEntitiesTryCreateTable(params Type[] entityTypes)
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> UseRouteConfig(Action<IShardingRouteConfigOptions> routeConfigure)
|
||||
{
|
||||
foreach (var entityType in entityTypes)
|
||||
{
|
||||
_createTableEntities.Add(entityType);
|
||||
}
|
||||
|
||||
_shardingRuntimeBuilder.UseRouteConfig(routeConfigure);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ISet<Type> GetCreateTableEntities()
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> UseRouteConfig(Action<IShardingProvider,IShardingRouteConfigOptions> routeConfigure)
|
||||
{
|
||||
return _createTableEntities;
|
||||
_shardingRuntimeBuilder.UseRouteConfig(routeConfigure);
|
||||
return this;
|
||||
}
|
||||
[Obsolete("plz use UseConfig")]
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> AddConfig(Action<ShardingConfigOptions> shardingConfigure)
|
||||
{
|
||||
_shardingRuntimeBuilder.UseConfig(shardingConfigure);
|
||||
return this;
|
||||
}
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> UseConfig(Action<ShardingConfigOptions> shardingConfigure)
|
||||
{
|
||||
_shardingRuntimeBuilder.UseConfig(shardingConfigure);
|
||||
return this;
|
||||
}
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> UseConfig(Action<IShardingProvider,ShardingConfigOptions> shardingConfigure)
|
||||
{
|
||||
_shardingRuntimeBuilder.UseConfig(shardingConfigure);
|
||||
return this;
|
||||
}
|
||||
public ShardingCoreConfigBuilder<TShardingDbContext> ReplaceService<TService, TImplement>(ServiceLifetime lifetime)
|
||||
{
|
||||
_shardingRuntimeBuilder.ReplaceService<TService, TImplement>(lifetime);
|
||||
return this;
|
||||
}
|
||||
|
||||
public readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
|
||||
|
||||
public bool AddParallelTables(params Type[] types)
|
||||
[Obsolete("plz use AddShardingCore")]
|
||||
public void EnsureConfig()
|
||||
{
|
||||
if (types.Length <= 0)
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{nameof(AddParallelTables)} args :[{string.Join(",", types.Select(o => o.Name))}] should more than one length");
|
||||
return _parallelTables.Add(new ParallelTableGroupNode(types.Select(o => new ParallelTableComparerType(o))));
|
||||
_services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeBuilder.Build(sp));
|
||||
}
|
||||
public ISet<ParallelTableGroupNode> GetParallelTableGroupNodes()
|
||||
public void AddShardingCore()
|
||||
{
|
||||
return _parallelTables;
|
||||
_services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeBuilder.Build(sp));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,14 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using ShardingCore.TableExists;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingConfigOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ShardingConfigOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id,如果是单配置可以用guid代替,如果是多配置该属性表示每个配置的id
|
||||
/// </summary>
|
||||
public string ConfigId { get; set; }
|
||||
/// <summary>
|
||||
/// 优先级多个配置之间的优先级
|
||||
/// </summary>
|
||||
public int Priority { get; set; }
|
||||
/// <summary>
|
||||
/// 全局配置最大的查询连接数限制,默认系统逻辑处理器<code>Environment.ProcessorCount</code>
|
||||
/// </summary>
|
||||
|
@ -52,13 +40,13 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
DefaultDataSourceName= dataSourceName?? throw new ArgumentNullException(nameof(dataSourceName));
|
||||
DefaultConnectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
|
||||
}
|
||||
public Func<IServiceProvider, IDictionary<string, string>> DataSourcesConfigure { get; private set; }
|
||||
public Func<IShardingProvider, IDictionary<string, string>> DataSourcesConfigure { get; private set; }
|
||||
/// <summary>
|
||||
/// 添加额外数据源
|
||||
/// </summary>
|
||||
/// <param name="extraDataSourceConfigure"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void AddExtraDataSource(Func<IServiceProvider, IDictionary<string, string>> extraDataSourceConfigure)
|
||||
public void AddExtraDataSource(Func<IShardingProvider, IDictionary<string, string>> extraDataSourceConfigure)
|
||||
{
|
||||
DataSourcesConfigure= extraDataSourceConfigure ?? throw new ArgumentNullException(nameof(extraDataSourceConfigure));
|
||||
}
|
||||
|
@ -72,7 +60,7 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
/// <param name="readConnStringGetStrategy">LatestFirstTime:DbContext缓存,LatestEveryTime:每次都是最新</param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void AddReadWriteSeparation(
|
||||
Func<IServiceProvider, IDictionary<string, IEnumerable<string>>> readWriteSeparationConfigure,
|
||||
Func<IShardingProvider, IDictionary<string, IEnumerable<string>>> readWriteSeparationConfigure,
|
||||
ReadStrategyEnum readStrategyEnum,
|
||||
bool defaultEnable = false,
|
||||
int defaultPriority = 10,
|
||||
|
@ -86,7 +74,7 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
ShardingReadWriteSeparationOptions.ReadConnStringGetStrategy= readConnStringGetStrategy;
|
||||
}
|
||||
public void AddReadWriteNodeSeparation(
|
||||
Func<IServiceProvider, IDictionary<string, IEnumerable<ReadNode>>> readWriteNodeSeparationConfigure,
|
||||
Func<IShardingProvider, IDictionary<string, IEnumerable<ReadNode>>> readWriteNodeSeparationConfigure,
|
||||
ReadStrategyEnum readStrategyEnum,
|
||||
bool defaultEnable = false,
|
||||
int defaultPriority = 10,
|
||||
|
@ -153,27 +141,37 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
{
|
||||
ShellDbContextConfigure = shellDbContextConfigure ?? throw new ArgumentNullException(nameof(shellDbContextConfigure));
|
||||
}
|
||||
public Func<IServiceProvider, IShardingComparer> ReplaceShardingComparerFactory { get; private set; } = sp => new CSharpLanguageShardingComparer();
|
||||
/// <summary>
|
||||
/// 替换默认的比较器
|
||||
/// </summary>
|
||||
/// <param name="newShardingComparerFactory"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer> newShardingComparerFactory)
|
||||
|
||||
// public Func<IServiceProvider, ITableEnsureManager<TShardingDbContext>> TableEnsureManagerFactory =
|
||||
// sp => new EmptyTableEnsureManager<TShardingDbContext>();
|
||||
//
|
||||
// public void ReplaceTableEnsureManager(
|
||||
// Func<IServiceProvider, ITableEnsureManager<TShardingDbContext>> tableEnsureManagerConfigure)
|
||||
// {
|
||||
// TableEnsureManagerFactory = tableEnsureManagerConfigure ??
|
||||
// throw new ArgumentNullException(nameof(tableEnsureManagerConfigure));
|
||||
// }
|
||||
|
||||
public void CheckArguments()
|
||||
{
|
||||
ReplaceShardingComparerFactory = newShardingComparerFactory ?? throw new ArgumentNullException(nameof(newShardingComparerFactory));
|
||||
if (string.IsNullOrWhiteSpace(DefaultDataSourceName))
|
||||
throw new ArgumentNullException(
|
||||
$"{nameof(DefaultDataSourceName)} plz call {nameof(AddDefaultDataSource)}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(DefaultConnectionString))
|
||||
throw new ArgumentNullException(
|
||||
$"{nameof(DefaultConnectionString)} plz call {nameof(AddDefaultDataSource)}");
|
||||
|
||||
if (ConnectionStringConfigure is null)
|
||||
throw new ArgumentNullException($"plz call {nameof(UseShardingQuery)}");
|
||||
if (ConnectionConfigure is null )
|
||||
throw new ArgumentNullException(
|
||||
$"plz call {nameof(UseShardingTransaction)}");
|
||||
|
||||
if (MaxQueryConnectionsLimit <= 0)
|
||||
throw new ArgumentException(
|
||||
$"{nameof(MaxQueryConnectionsLimit)} should greater than and equal 1");
|
||||
}
|
||||
|
||||
public Func<IServiceProvider, ITableEnsureManager<TShardingDbContext>> TableEnsureManagerFactory =
|
||||
sp => new EmptyTableEnsureManager<TShardingDbContext>();
|
||||
|
||||
public void ReplaceTableEnsureManager(
|
||||
Func<IServiceProvider, ITableEnsureManager<TShardingDbContext>> tableEnsureManagerConfigure)
|
||||
{
|
||||
TableEnsureManagerFactory = tableEnsureManagerConfigure ??
|
||||
throw new ArgumentNullException(nameof(tableEnsureManagerConfigure));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingMultiConfigurationOptions<TShardingDbContext> : IShardingConfigurationOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; set; } =
|
||||
ShardingConfigurationStrategyEnum.ThrowIfNull;
|
||||
|
||||
private Dictionary<string, ShardingConfigOptions<TShardingDbContext>> _shardingGlobalConfigOptions = new ();
|
||||
|
||||
public void AddShardingGlobalConfigOptions(ShardingConfigOptions<TShardingDbContext> shardingConfigOptions)
|
||||
{
|
||||
if (_shardingGlobalConfigOptions.ContainsKey(shardingConfigOptions.ConfigId))
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add config id:[{shardingConfigOptions.ConfigId}]");
|
||||
|
||||
_shardingGlobalConfigOptions.Add(shardingConfigOptions.ConfigId, shardingConfigOptions);
|
||||
}
|
||||
|
||||
public ShardingConfigOptions<TShardingDbContext>[] GetAllShardingGlobalConfigOptions()
|
||||
{
|
||||
return _shardingGlobalConfigOptions.Values.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingReadWriteSeparationOptions
|
||||
{
|
||||
public Func<IServiceProvider, IDictionary<string, IEnumerable<string>>> ReadWriteSeparationConfigure { get; set; }
|
||||
public Func<IServiceProvider, IDictionary<string, IEnumerable<ReadNode>>> ReadWriteNodeSeparationConfigure { get; set; }
|
||||
public Func<IShardingProvider, IDictionary<string, IEnumerable<string>>> ReadWriteSeparationConfigure { get; set; }
|
||||
public Func<IShardingProvider, IDictionary<string, IEnumerable<ReadNode>>> ReadWriteNodeSeparationConfigure { get; set; }
|
||||
|
||||
public ReadStrategyEnum ReadStrategy { get; set; } = ReadStrategyEnum.Loop;
|
||||
public bool DefaultEnable { get; set; } = false;
|
||||
|
|
|
@ -15,46 +15,49 @@ using ShardingCore.Sharding.ParallelTables;
|
|||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingEntityConfigOptions<TShardingDbContext> : IShardingEntityConfigOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class ShardingRouteConfigOptions : IShardingRouteConfigOptions
|
||||
{
|
||||
private readonly IDictionary<Type, Type> _virtualDataSourceRoutes = new Dictionary<Type, Type>();
|
||||
private readonly IDictionary<Type, Type> _virtualTableRoutes = new Dictionary<Type, Type>();
|
||||
private readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
public bool? CreateShardingTableOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 是否在启动时创建数据库
|
||||
/// </summary>
|
||||
public bool? CreateDataBaseOnlyOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 当查询遇到没有路由被命中时是否抛出错误
|
||||
/// </summary>
|
||||
public bool ThrowIfQueryRouteNotMatch { get; set; } = true;
|
||||
///// <summary>
|
||||
///// 全局启用分表路由表达式缓存,仅缓存单个表达式
|
||||
///// </summary>
|
||||
//public bool? EnableTableRouteCompileCache { get; set; }
|
||||
///// <summary>
|
||||
///// 全局启用分库路由表达式缓存,仅缓存单个表达式
|
||||
///// </summary>
|
||||
//public bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
// /// <summary>
|
||||
// /// 如果数据库不存在就创建并且创建表除了分表的
|
||||
// /// </summary>
|
||||
// public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 是否需要在启动时创建分表
|
||||
// /// </summary>
|
||||
// public bool? CreateShardingTableOnStart { get; set; }
|
||||
// /// <summary>
|
||||
// /// 是否在启动时创建数据库
|
||||
// /// </summary>
|
||||
// public bool? CreateDataBaseOnlyOnStart { get; set; }
|
||||
// /// <summary>
|
||||
// /// 当查询遇到没有路由被命中时是否抛出错误
|
||||
// /// </summary>
|
||||
// public bool ThrowIfQueryRouteNotMatch { get; set; } = true;
|
||||
// ///// <summary>
|
||||
// ///// 全局启用分表路由表达式缓存,仅缓存单个表达式
|
||||
// ///// </summary>
|
||||
// //public bool? EnableTableRouteCompileCache { get; set; }
|
||||
// ///// <summary>
|
||||
// ///// 全局启用分库路由表达式缓存,仅缓存单个表达式
|
||||
// ///// </summary>
|
||||
// //public bool? EnableDataSourceRouteCompileCache { get; set; }
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
public bool? IgnoreCreateTableError { get; set; } = false;
|
||||
|
||||
public bool ThrowIfQueryRouteNotMatch { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// 添加分库路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
public void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute
|
||||
public void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute
|
||||
{
|
||||
var routeType = typeof(TRoute);
|
||||
AddShardingDataSourceRoute(routeType);
|
||||
|
@ -81,7 +84,7 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
|
||||
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
|
||||
{
|
||||
var routeType = typeof(TRoute);
|
||||
AddShardingTableRoute(routeType);
|
||||
|
@ -151,48 +154,28 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
{
|
||||
return _parallelTables;
|
||||
}
|
||||
/// <summary>
|
||||
/// 多个DbContext事务传播委托
|
||||
/// </summary>
|
||||
public Action<DbConnection, DbContextOptionsBuilder> ConnectionConfigure { get; private set; }
|
||||
/// <summary>
|
||||
/// 初始DbContext的创建委托
|
||||
/// </summary>
|
||||
public Action<string, DbContextOptionsBuilder> ConnectionStringConfigure { get; private set; }
|
||||
/// <summary>
|
||||
/// 仅内部DbContext生效的配置委托
|
||||
/// </summary>
|
||||
public Action<DbContextOptionsBuilder> ExecutorDbContextConfigure { get; private set; }
|
||||
public Action<DbContextOptionsBuilder> ShellDbContextConfigure { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 如何使用字符串创建DbContext
|
||||
/// </summary>
|
||||
public void UseShardingQuery(Action<string, DbContextOptionsBuilder> queryConfigure)
|
||||
{
|
||||
ConnectionStringConfigure = queryConfigure ?? throw new ArgumentNullException(nameof(queryConfigure));
|
||||
}
|
||||
/// <summary>
|
||||
/// 如何传递事务到其他DbContext
|
||||
/// </summary>
|
||||
public void UseShardingTransaction(Action<DbConnection, DbContextOptionsBuilder> transactionConfigure)
|
||||
{
|
||||
ConnectionConfigure = transactionConfigure ?? throw new ArgumentNullException(nameof(transactionConfigure));
|
||||
}
|
||||
/// <summary>
|
||||
/// 仅内部真实DbContext配置的方法
|
||||
/// </summary>
|
||||
/// <param name="executorDbContextConfigure"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public void UseExecutorDbContextConfigure(Action<DbContextOptionsBuilder> executorDbContextConfigure)
|
||||
{
|
||||
ExecutorDbContextConfigure = executorDbContextConfigure ?? throw new ArgumentNullException(nameof(executorDbContextConfigure));
|
||||
}
|
||||
|
||||
public void UseShellDbContextConfigure(Action<DbContextOptionsBuilder> shellDbContextConfigure)
|
||||
{
|
||||
ShellDbContextConfigure = shellDbContextConfigure ?? throw new ArgumentNullException(nameof(shellDbContextConfigure));
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 仅内部DbContext生效的配置委托
|
||||
// /// </summary>
|
||||
// public Action<DbContextOptionsBuilder> ExecutorDbContextConfigure { get; private set; }
|
||||
// public Action<DbContextOptionsBuilder> ShellDbContextConfigure { get; private set; }
|
||||
//
|
||||
// /// <summary>
|
||||
// /// 仅内部真实DbContext配置的方法
|
||||
// /// </summary>
|
||||
// /// <param name="executorDbContextConfigure"></param>
|
||||
// /// <exception cref="ArgumentNullException"></exception>
|
||||
// public void UseExecutorDbContextConfigure(Action<DbContextOptionsBuilder> executorDbContextConfigure)
|
||||
// {
|
||||
// ExecutorDbContextConfigure = executorDbContextConfigure ?? throw new ArgumentNullException(nameof(executorDbContextConfigure));
|
||||
// }
|
||||
//
|
||||
// public void UseShellDbContextConfigure(Action<DbContextOptionsBuilder> shellDbContextConfigure)
|
||||
// {
|
||||
// ShellDbContextConfigure = shellDbContextConfigure ?? throw new ArgumentNullException(nameof(shellDbContextConfigure));
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingConfigurations
|
||||
{
|
||||
public class ShardingSingleConfigurationOptions<TShardingDbContext> : IShardingConfigurationOptions<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
||||
private ShardingConfigOptions<TShardingDbContext> _shardingConfigOptions;
|
||||
public ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; set; } =
|
||||
ShardingConfigurationStrategyEnum.ThrowIfNull;
|
||||
|
||||
public void AddShardingGlobalConfigOptions(ShardingConfigOptions<TShardingDbContext> shardingConfigOptions)
|
||||
{
|
||||
if (_shardingConfigOptions != null)
|
||||
throw new ShardingCoreInvalidOperationException($"repeat add {nameof(ShardingConfigOptions<TShardingDbContext>)}");
|
||||
_shardingConfigOptions= shardingConfigOptions;
|
||||
}
|
||||
|
||||
public ShardingConfigOptions<TShardingDbContext>[] GetAllShardingGlobalConfigOptions()
|
||||
{
|
||||
return new[] { _shardingConfigOptions };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/21 13:04:38
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingConstant
|
||||
{
|
||||
public const string MULTI_ENTITIES_QUERY = "MULTI_ENTITIES_QUERY";
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
internal class ShardingCreatorHelper
|
||||
{
|
||||
private static ConcurrentDictionary<Type, Func<object[], object>> _creator;
|
||||
private ShardingCreatorHelper() { }
|
||||
|
||||
static ShardingCreatorHelper()
|
||||
{
|
||||
_creator = new ConcurrentDictionary<Type, Func<object[], object>>();
|
||||
}
|
||||
public static object CreateInstance(Type targetType,params object[] args)
|
||||
{
|
||||
var creator = _creator.GetOrAdd(targetType,key=> GetActivator(key));
|
||||
return creator(args);
|
||||
}
|
||||
|
||||
private static Func<object[],object> GetActivator(Type targetType)
|
||||
{
|
||||
ConstructorInfo ctor = targetType.GetConstructors().First();
|
||||
Type type = ctor.DeclaringType;
|
||||
ParameterInfo[] paramsInfo = ctor.GetParameters();
|
||||
|
||||
//create a single param of type object[]
|
||||
ParameterExpression param =
|
||||
Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
Expression[] argsExp =
|
||||
new Expression[paramsInfo.Length];
|
||||
|
||||
//pick each arg from the params array
|
||||
//and create a typed expression of them
|
||||
for (int i = 0; i < paramsInfo.Length; i++)
|
||||
{
|
||||
Expression index = Expression.Constant(i);
|
||||
Type paramType = paramsInfo[i].ParameterType;
|
||||
|
||||
Expression paramAccessorExp =
|
||||
Expression.ArrayIndex(param, index);
|
||||
|
||||
Expression paramCastExp =
|
||||
Expression.Convert(paramAccessorExp, paramType);
|
||||
|
||||
argsExp[i] = paramCastExp;
|
||||
}
|
||||
|
||||
//make a NewExpression that calls the
|
||||
//ctor with the args we just created
|
||||
NewExpression newExp = Expression.New(ctor, argsExp);
|
||||
|
||||
//create a lambda with the New
|
||||
//Expression as body and our param object[] as arg
|
||||
//compile it
|
||||
var compiled =
|
||||
Expression.Lambda<Func<object[],object>>(newExp, param).Compile();
|
||||
|
||||
return compiled;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:用户数据库分数据源时进行判断
|
||||
* @Date: Friday, 05 February 2021 12:53:46
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 数据源分库规则字段
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public class ShardingDataSourceKeyAttribute: Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否需要在启动的时候创建表
|
||||
/// </summary>
|
||||
public ShardingKeyAutoCreateTableEnum AutoCreateDataSourceTableOnStart { get; set; } = ShardingKeyAutoCreateTableEnum.UnKnown;
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:用户数据库分数据源时进行判断
|
||||
* @Date: Friday, 05 February 2021 12:53:46
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 数据源分库额外规则字段
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public class ShardingExtraDataSourceKeyAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 16 December 2020 11:04:51
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 分片额外配置
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public class ShardingExtraTableKeyAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 16 December 2020 11:04:51
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// AbstractVirtualTableRoute 最基础分表规则 需要自己解析如何分表
|
||||
/// 仅ShardingMode为Custom:以下接口提供自定义分表
|
||||
/// AbstractShardingKeyObjectEqualVirtualRoute 自定义分表
|
||||
/// SimpleShardingKeyStringModVirtualRoute 默认对AbstractShardingKeyObjectEqualVirtualRoute的实现,字符串按取模分表
|
||||
/// 仅ShardingMode非Custom:以下接口提供自动按时间分表
|
||||
/// SimpleShardingDateByDayVirtualRoute 分表
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public class ShardingTableKeyAttribute : Attribute
|
||||
{
|
||||
public const string DEFAULT_TABLE_SEPARATOR = "_";
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要在启动的时候创建表
|
||||
/// </summary>
|
||||
public ShardingKeyAutoCreateTableEnum AutoCreateTableOnStart { get; set; } = ShardingKeyAutoCreateTableEnum.UnKnown;
|
||||
|
||||
/// <summary>
|
||||
/// 分表尾巴前缀
|
||||
/// </summary>
|
||||
public string TableSeparator { get; set; } = DEFAULT_TABLE_SEPARATOR;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,4 @@ namespace ShardingCore.Core.TrackerManagers
|
|||
bool EntityUseTrack(Type entityType);
|
||||
bool IsDbContextModel(Type entityType);
|
||||
}
|
||||
public interface ITrackerManager<TShardingDbContext>: ITrackerManager where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace ShardingCore.Core.TrackerManagers
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class TrackerManager<TShardingDbContext>: ITrackerManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class TrackerManager: ITrackerManager
|
||||
{
|
||||
private readonly ConcurrentDictionary<Type,bool> _dbContextModels = new ();
|
||||
|
||||
|
|
|
@ -6,23 +6,14 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using ShardingCore.TableExists;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public abstract class AbstractVirtualDataSourceConfigurationParams<TShardingDbContext>:IVirtualDataSourceConfigurationParams<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public abstract class AbstractVirtualDataSourceConfigurationParams:IVirtualDataSourceConfigurationParams
|
||||
{
|
||||
public abstract string ConfigId { get; }
|
||||
public abstract int Priority { get; }
|
||||
public virtual int MaxQueryConnectionsLimit { get; } = Environment.ProcessorCount;
|
||||
public virtual ConnectionModeEnum ConnectionMode { get; } = ConnectionModeEnum.SYSTEM_AUTO;
|
||||
public abstract string DefaultDataSourceName { get; }
|
||||
|
@ -33,12 +24,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
public virtual bool? ReadWriteDefaultEnable { get; }
|
||||
public virtual int? ReadWriteDefaultPriority { get; }
|
||||
public virtual ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
public virtual IShardingComparer ShardingComparer { get; } = new CSharpLanguageShardingComparer();
|
||||
|
||||
public virtual ITableEnsureManager TableEnsureManager { get; } =
|
||||
new EmptyTableEnsureManager<TShardingDbContext>();
|
||||
|
||||
|
||||
|
||||
public abstract DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public interface IVirtualDataSourceAccessor
|
||||
{
|
||||
VirtualDataSourceContext DataSourceContext { get; set; }
|
||||
}
|
||||
}
|
|
@ -4,20 +4,11 @@ using ShardingCore.Sharding.ReadWriteConfigurations;
|
|||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public interface IVirtualDataSourceConfigurationParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
string ConfigId { get; }
|
||||
/// <summary>
|
||||
/// 优先级
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
/// <summary>
|
||||
/// 不能小于等于0 should greater than or equal zero
|
||||
/// </summary>
|
||||
|
@ -52,14 +43,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// </summary>
|
||||
ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
/// <summary>
|
||||
/// 不能为空 should not null
|
||||
/// </summary>
|
||||
IShardingComparer ShardingComparer { get; }
|
||||
/// <summary>
|
||||
/// 表确认管理者
|
||||
/// </summary>
|
||||
ITableEnsureManager TableEnsureManager { get; }
|
||||
/// <summary>
|
||||
/// 如何根据connectionString 配置 DbContextOptionsBuilder
|
||||
/// </summary>
|
||||
/// <param name="connectionString"></param>
|
||||
|
@ -89,10 +72,4 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// <returns></returns>
|
||||
bool UseReadWriteSeparation();
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceConfigurationParams<TShardingDbContext> : IVirtualDataSourceConfigurationParams
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
{
|
||||
public interface IVirtualDataSourceManager
|
||||
{
|
||||
bool IsMultiShardingConfiguration { get; }
|
||||
ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; }
|
||||
IVirtualDataSource GetCurrentVirtualDataSource();
|
||||
IVirtualDataSource GetVirtualDataSource(string configId);
|
||||
List<IVirtualDataSource> GetAllVirtualDataSources();
|
||||
bool ContansConfigId(string configId);
|
||||
|
||||
/// <summary>
|
||||
/// 创建分片配置scope
|
||||
/// </summary>
|
||||
/// <param name="configId"></param>
|
||||
/// <returns></returns>
|
||||
VirtualDataSourceScope CreateScope(string configId);
|
||||
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
IVirtualDataSource<TShardingDbContext> GetCurrentVirtualDataSource();
|
||||
IVirtualDataSource<TShardingDbContext> GetVirtualDataSource(string configId);
|
||||
List<IVirtualDataSource<TShardingDbContext>> GetAllVirtualDataSources();
|
||||
bool AddVirtualDataSource(IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams);
|
||||
void SetDefaultIfMultiConfiguration();
|
||||
}
|
||||
}
|
|
@ -27,11 +27,4 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// <exception cref="ShardingCoreInvalidOperationException">对象未配置分库</exception>
|
||||
bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceRouteManager<TShardingDbContext> : IVirtualDataSourceRouteManager
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity:class;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common
|
||||
{
|
||||
public enum ShardingConfigurationStrategyEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回空
|
||||
/// </summary>
|
||||
ReturnNull = 1,
|
||||
/// <summary>
|
||||
/// 抛出异常
|
||||
/// </summary>
|
||||
ThrowIfNull = 1 << 1,
|
||||
/// <summary>
|
||||
/// 返回优先级最高的
|
||||
/// </summary>
|
||||
ReturnHighPriority = 1 << 2
|
||||
}
|
||||
}
|
|
@ -2,12 +2,10 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
|
@ -22,14 +20,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
public interface IVirtualDataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
string ConfigId { get; }
|
||||
/// <summary>
|
||||
/// 当前配置的优先级
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
/// <summary>
|
||||
/// 数据源配置
|
||||
/// </summary>
|
||||
|
@ -129,12 +119,4 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
IDictionary<string, string> GetDataSources();
|
||||
}
|
||||
/// <summary>
|
||||
/// 虚拟数据源 连接所有的实际数据源
|
||||
/// </summary>
|
||||
public interface IVirtualDataSource<TShardingDbContext> : IVirtualDataSource
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity:class;
|
||||
}
|
||||
}
|
|
@ -1,29 +1,21 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using ShardingCore.TableExists;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class SimpleVirtualDataSourceConfigurationParams<TShardingDbContext>: AbstractVirtualDataSourceConfigurationParams<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class SimpleVirtualDataSourceConfigurationParams: AbstractVirtualDataSourceConfigurationParams
|
||||
{
|
||||
private readonly ShardingConfigOptions<TShardingDbContext> _options;
|
||||
private readonly IShardingEntityConfigOptions<TShardingDbContext> _shardingEntityConfigOptions;
|
||||
public override string ConfigId { get; }
|
||||
public override int Priority { get; }
|
||||
private readonly ShardingConfigOptions _options;
|
||||
public override int MaxQueryConnectionsLimit { get; }
|
||||
public override ConnectionModeEnum ConnectionMode { get; }
|
||||
public override string DefaultDataSourceName { get; }
|
||||
|
@ -34,29 +26,22 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
public override bool? ReadWriteDefaultEnable { get; }
|
||||
public override int? ReadWriteDefaultPriority { get; }
|
||||
public override ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
public override IShardingComparer ShardingComparer { get; }
|
||||
public override ITableEnsureManager TableEnsureManager { get; }
|
||||
|
||||
public SimpleVirtualDataSourceConfigurationParams(IServiceProvider serviceProvider,ShardingConfigOptions<TShardingDbContext> options)
|
||||
public SimpleVirtualDataSourceConfigurationParams(IShardingProvider shardingProvider,ShardingConfigOptions options)
|
||||
{
|
||||
_shardingEntityConfigOptions = serviceProvider.GetService<IShardingEntityConfigOptions<TShardingDbContext>>();
|
||||
_options = options;
|
||||
ConfigId = options.ConfigId;
|
||||
Priority = options.Priority;
|
||||
MaxQueryConnectionsLimit = options.MaxQueryConnectionsLimit;
|
||||
ConnectionMode = options.ConnectionMode;
|
||||
DefaultDataSourceName = options.DefaultDataSourceName;
|
||||
DefaultConnectionString = options.DefaultConnectionString;
|
||||
ExtraDataSources = options.DataSourcesConfigure?.Invoke(serviceProvider)??new ConcurrentDictionary<string, string>();
|
||||
ShardingComparer = options.ReplaceShardingComparerFactory?.Invoke(serviceProvider) ??
|
||||
new CSharpLanguageShardingComparer();
|
||||
TableEnsureManager = options.TableEnsureManagerFactory?.Invoke(serviceProvider) ??
|
||||
new EmptyTableEnsureManager<TShardingDbContext>();
|
||||
ExtraDataSources = options.DataSourcesConfigure?.Invoke(shardingProvider)??new ConcurrentDictionary<string, string>();
|
||||
|
||||
|
||||
if (options.ShardingReadWriteSeparationOptions != null)
|
||||
{
|
||||
if (options.ShardingReadWriteSeparationOptions.ReadWriteNodeSeparationConfigure != null)
|
||||
{
|
||||
var readConfig = options.ShardingReadWriteSeparationOptions.ReadWriteNodeSeparationConfigure?.Invoke(serviceProvider);
|
||||
var readConfig = options.ShardingReadWriteSeparationOptions.ReadWriteNodeSeparationConfigure?.Invoke(shardingProvider);
|
||||
if (readConfig != null)
|
||||
{
|
||||
ReadWriteNodeSeparationConfigs = readConfig.ToDictionary(kv=>kv.Key,kv=>kv.Value.ToArray());
|
||||
|
@ -64,7 +49,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
}
|
||||
else
|
||||
{
|
||||
var nodeConfig = options.ShardingReadWriteSeparationOptions.ReadWriteSeparationConfigure?.Invoke(serviceProvider);
|
||||
var nodeConfig = options.ShardingReadWriteSeparationOptions.ReadWriteSeparationConfigure?.Invoke(shardingProvider);
|
||||
if (nodeConfig != null)
|
||||
{
|
||||
ReadWriteNodeSeparationConfigs = nodeConfig.ToDictionary(kv => kv.Key,
|
||||
|
@ -81,71 +66,43 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
if(_options.ConnectionStringConfigure==null&&_shardingEntityConfigOptions.ConnectionStringConfigure==null)
|
||||
if(_options.ConnectionStringConfigure==null)
|
||||
{
|
||||
throw new InvalidOperationException($"unknown {nameof(UseDbContextOptionsBuilder)} by connection string");
|
||||
}
|
||||
if (_options.ConnectionStringConfigure != null)
|
||||
{
|
||||
_options.ConnectionStringConfigure.Invoke(connectionString, dbContextOptionsBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_shardingEntityConfigOptions.ConnectionStringConfigure.Invoke(connectionString, dbContextOptionsBuilder);
|
||||
}
|
||||
_options.ConnectionStringConfigure.Invoke(connectionString, dbContextOptionsBuilder);
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
if (_options.ConnectionConfigure == null && _shardingEntityConfigOptions.ConnectionConfigure == null)
|
||||
if (_options.ConnectionConfigure == null )
|
||||
{
|
||||
throw new InvalidOperationException($"unknown {nameof(UseDbContextOptionsBuilder)} by connection");
|
||||
}
|
||||
if (_options.ConnectionConfigure != null)
|
||||
{
|
||||
_options.ConnectionConfigure.Invoke(dbConnection, dbContextOptionsBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_shardingEntityConfigOptions.ConnectionConfigure.Invoke(dbConnection, dbContextOptionsBuilder);
|
||||
}
|
||||
_options.ConnectionConfigure.Invoke(dbConnection, dbContextOptionsBuilder);
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public override void UseShellDbContextOptionBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
if (_options.ShellDbContextConfigure == null && _shardingEntityConfigOptions.ShellDbContextConfigure == null)
|
||||
if (_options.ShellDbContextConfigure == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_options.ShellDbContextConfigure != null)
|
||||
{
|
||||
_options.ShellDbContextConfigure.Invoke(dbContextOptionsBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_shardingEntityConfigOptions.ShellDbContextConfigure?.Invoke(dbContextOptionsBuilder);
|
||||
}
|
||||
_options.ShellDbContextConfigure.Invoke(dbContextOptionsBuilder);
|
||||
}
|
||||
|
||||
public override void UseExecutorDbContextOptionBuilder(DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
if (_options.ExecutorDbContextConfigure == null && _shardingEntityConfigOptions.ExecutorDbContextConfigure == null)
|
||||
if (_options.ExecutorDbContextConfigure == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_options.ExecutorDbContextConfigure != null)
|
||||
{
|
||||
_options.ExecutorDbContextConfigure.Invoke(dbContextOptionsBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
_shardingEntityConfigOptions.ExecutorDbContextConfigure?.Invoke(dbContextOptionsBuilder);
|
||||
}
|
||||
_options.ExecutorDbContextConfigure.Invoke(dbContextOptionsBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
|||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
using ShardingCore.Utils;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
|
@ -28,27 +28,23 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
* @Date: Friday, 05 February 2021 15:21:04
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class VirtualDataSource<TShardingDbContext> : IVirtualDataSource<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class VirtualDataSource : IVirtualDataSource
|
||||
{
|
||||
public IVirtualDataSourceConfigurationParams ConfigurationParams { get; }
|
||||
public IConnectionStringManager ConnectionStringManager { get; }
|
||||
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _dataSourceRouteManager;
|
||||
private readonly IEntityMetadataManager _entityMetadataManager;
|
||||
private readonly IVirtualDataSourceRouteManager _dataSourceRouteManager;
|
||||
|
||||
private readonly IPhysicDataSourcePool _physicDataSourcePool;
|
||||
|
||||
public string ConfigId => ConfigurationParams.ConfigId;
|
||||
public int Priority => ConfigurationParams.Priority;
|
||||
public string DefaultDataSourceName { get; private set; }
|
||||
public string DefaultConnectionString { get; private set; }
|
||||
public bool UseReadWriteSeparation { get; }
|
||||
|
||||
public VirtualDataSource(IEntityMetadataManager<TShardingDbContext> entityMetadataManager, IVirtualDataSourceRouteManager<TShardingDbContext> dataSourceRouteManager, IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
public VirtualDataSource(IEntityMetadataManager entityMetadataManager, IVirtualDataSourceRouteManager dataSourceRouteManager, IVirtualDataSourceConfigurationParams configurationParams,IReadWriteConnectorFactory readWriteConnectorFactory)
|
||||
{
|
||||
Check.NotNull(configurationParams, nameof(configurationParams));
|
||||
Check.NotNull(configurationParams.ExtraDataSources, nameof(configurationParams.ExtraDataSources));
|
||||
Check.NotNull(configurationParams.ShardingComparer, nameof(configurationParams.ShardingComparer));
|
||||
if(configurationParams.MaxQueryConnectionsLimit<=0)
|
||||
throw new ArgumentOutOfRangeException(nameof(configurationParams.MaxQueryConnectionsLimit));
|
||||
ConfigurationParams = configurationParams;
|
||||
|
@ -65,7 +61,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
if (UseReadWriteSeparation)
|
||||
{
|
||||
CheckReadWriteSeparation();
|
||||
ConnectionStringManager = new ReadWriteConnectionStringManager(this);
|
||||
ConnectionStringManager = new ReadWriteConnectionStringManager(this,readWriteConnectorFactory);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -99,11 +95,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
return _dataSourceRouteManager.GetRoute(entityType);
|
||||
}
|
||||
|
||||
public IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity : class
|
||||
{
|
||||
return _dataSourceRouteManager.GetRoute<TEntity>();
|
||||
}
|
||||
|
||||
public List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig)
|
||||
{
|
||||
if (!_entityMetadataManager.IsShardingDataSource(entityType))
|
||||
|
@ -151,7 +142,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
/// <exception cref="ShardingCoreNotFoundException"></exception>
|
||||
public IPhysicDataSource GetPhysicDataSource(string dataSourceName)
|
||||
{
|
||||
Check.NotNull(dataSourceName, "data source name is null,plz confirm IShardingBootstrapper.Star()");
|
||||
Check.NotNull(dataSourceName, $"data source name is null,plz confirm {dataSourceName} add in virtual data source");
|
||||
var dataSource = _physicDataSourcePool.TryGet(dataSourceName);
|
||||
if (null == dataSource)
|
||||
throw new ShardingCoreNotFoundException($"data source:[{dataSourceName}]");
|
||||
|
@ -227,7 +218,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
var doUseDbContextOptionsBuilder = ConfigurationParams.UseDbContextOptionsBuilder(connectionString, dbContextOptionsBuilder);
|
||||
doUseDbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
doUseDbContextOptionsBuilder.UseInnerDbContextSharding();
|
||||
ConfigurationParams.UseExecutorDbContextOptionBuilder(dbContextOptionsBuilder);
|
||||
return doUseDbContextOptionsBuilder;
|
||||
}
|
||||
|
@ -236,7 +227,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
var doUseDbContextOptionsBuilder = ConfigurationParams.UseDbContextOptionsBuilder(dbConnection, dbContextOptionsBuilder);
|
||||
doUseDbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
doUseDbContextOptionsBuilder.UseInnerDbContextSharding();
|
||||
ConfigurationParams.UseExecutorDbContextOptionBuilder(dbContextOptionsBuilder);
|
||||
return doUseDbContextOptionsBuilder;
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceAccessor: IVirtualDataSourceAccessor
|
||||
{
|
||||
private static AsyncLocal<VirtualDataSourceContext> _shardingConfigurationContext = new AsyncLocal<VirtualDataSourceContext>();
|
||||
|
||||
/// <summary>
|
||||
/// sharding route context use in using code block
|
||||
/// </summary>
|
||||
public VirtualDataSourceContext DataSourceContext
|
||||
{
|
||||
get => _shardingConfigurationContext.Value;
|
||||
set => _shardingConfigurationContext.Value = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceContext
|
||||
{
|
||||
public string ConfigId { get; }
|
||||
|
||||
public VirtualDataSourceContext(string configId)
|
||||
{
|
||||
ConfigId = configId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ShardingConfigurations;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Common;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IShardingConfigurationOptions<TShardingDbContext> _options;
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IVirtualDataSourceRouteManager<TShardingDbContext> _virtualDataSourceRouteManager;
|
||||
private readonly IVirtualDataSourceAccessor _virtualDataSourceAccessor;
|
||||
|
||||
private readonly ConcurrentDictionary<string, IVirtualDataSource> _virtualDataSources = new();
|
||||
|
||||
private string _defaultConfigId;
|
||||
private IVirtualDataSource _defaultVirtualDataSource;
|
||||
public VirtualDataSourceManager(IServiceProvider serviceProvider, IShardingConfigurationOptions<TShardingDbContext> options, IEntityMetadataManager<TShardingDbContext> entityMetadataManager, IVirtualDataSourceRouteManager<TShardingDbContext> virtualDataSourceRouteManager, IVirtualDataSourceAccessor virtualDataSourceAccessor)
|
||||
{
|
||||
|
||||
_options = options;
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
|
||||
var allShardingGlobalConfigOptions = options.GetAllShardingGlobalConfigOptions();
|
||||
if (allShardingGlobalConfigOptions.IsEmpty())
|
||||
throw new ArgumentException($"sharding virtual data source is empty");
|
||||
_virtualDataSourceAccessor = virtualDataSourceAccessor;
|
||||
if (options is ShardingMultiConfigurationOptions<TShardingDbContext> shardingMultiConfigurationOptions)
|
||||
{
|
||||
IsMultiShardingConfiguration = true;
|
||||
ShardingConfigurationStrategy = shardingMultiConfigurationOptions.ShardingConfigurationStrategy;
|
||||
}
|
||||
else if (options is ShardingSingleConfigurationOptions<TShardingDbContext> shardingSingleConfigurationOptions)
|
||||
{
|
||||
IsMultiShardingConfiguration = false;
|
||||
ShardingConfigurationStrategy = shardingSingleConfigurationOptions.ShardingConfigurationStrategy;
|
||||
}
|
||||
foreach (var shardingGlobalConfigOption in allShardingGlobalConfigOptions)
|
||||
{
|
||||
var simpleVirtualDataSourceConfigurationParams = new SimpleVirtualDataSourceConfigurationParams<TShardingDbContext>(serviceProvider, shardingGlobalConfigOption);
|
||||
AddVirtualDataSource(simpleVirtualDataSourceConfigurationParams);
|
||||
}
|
||||
if (!IsMultiShardingConfiguration)
|
||||
{
|
||||
if (_defaultVirtualDataSource != null || _defaultConfigId != null)
|
||||
throw new ShardingCoreInvalidOperationException("set sharding configuration error");
|
||||
_defaultConfigId = _virtualDataSources.First().Key;
|
||||
_defaultVirtualDataSource = _virtualDataSources.First().Value;
|
||||
}
|
||||
else if (ShardingConfigurationStrategy == ShardingConfigurationStrategyEnum.ReturnHighPriority)
|
||||
{
|
||||
var maxShardingConfiguration = _virtualDataSources.Values.OrderByDescending(o => o.Priority).FirstOrDefault();
|
||||
_defaultVirtualDataSource = maxShardingConfiguration;
|
||||
_defaultConfigId = maxShardingConfiguration.ConfigId;
|
||||
}
|
||||
}
|
||||
public bool IsMultiShardingConfiguration { get; }
|
||||
public ShardingConfigurationStrategyEnum ShardingConfigurationStrategy { get; }
|
||||
public IVirtualDataSource GetCurrentVirtualDataSource()
|
||||
{
|
||||
if (!IsMultiShardingConfiguration)
|
||||
return _defaultVirtualDataSource;
|
||||
var configId = _virtualDataSourceAccessor.DataSourceContext?.ConfigId;
|
||||
if (!string.IsNullOrWhiteSpace(configId))
|
||||
{
|
||||
var hasValue = _virtualDataSources.TryGetValue(configId, out var virtualDataSource);
|
||||
if (hasValue)
|
||||
{
|
||||
return virtualDataSource;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ShardingConfigurationStrategy)
|
||||
{
|
||||
case ShardingConfigurationStrategyEnum.ReturnNull: return null;
|
||||
case ShardingConfigurationStrategyEnum.ReturnHighPriority: return _defaultVirtualDataSource;
|
||||
case ShardingConfigurationStrategyEnum.ThrowIfNull: throw new ShardingCoreNotFoundException($"no configuration,config id:[{configId}]");
|
||||
default:
|
||||
throw new ShardingCoreException(
|
||||
$"unknown {nameof(ShardingConfigurationStrategyEnum)}:[{ShardingConfigurationStrategy}]");
|
||||
}
|
||||
}
|
||||
|
||||
IVirtualDataSource<TShardingDbContext> IVirtualDataSourceManager<TShardingDbContext>.GetVirtualDataSource(string configId)
|
||||
{
|
||||
return (IVirtualDataSource<TShardingDbContext>)GetVirtualDataSource(configId);
|
||||
}
|
||||
|
||||
public IVirtualDataSource GetVirtualDataSource(string configId)
|
||||
{
|
||||
var hasValue = _virtualDataSources.TryGetValue(configId, out var virtualDataSource);
|
||||
if (hasValue)
|
||||
{
|
||||
return virtualDataSource;
|
||||
}
|
||||
switch (ShardingConfigurationStrategy)
|
||||
{
|
||||
case ShardingConfigurationStrategyEnum.ReturnNull: return null;
|
||||
case ShardingConfigurationStrategyEnum.ReturnHighPriority: return _defaultVirtualDataSource;
|
||||
case ShardingConfigurationStrategyEnum.ThrowIfNull: throw new ShardingCoreNotFoundException($"no configuration,config id:[{configId}]");
|
||||
default:
|
||||
throw new ShardingCoreException(
|
||||
$"unknown {nameof(ShardingConfigurationStrategyEnum)}:[{ShardingConfigurationStrategy}]");
|
||||
}
|
||||
}
|
||||
|
||||
List<IVirtualDataSource<TShardingDbContext>> IVirtualDataSourceManager<TShardingDbContext>.GetAllVirtualDataSources()
|
||||
{
|
||||
return GetAllVirtualDataSources().Select(o => (IVirtualDataSource<TShardingDbContext>)o).ToList();
|
||||
}
|
||||
|
||||
public bool ContansConfigId(string configId)
|
||||
{
|
||||
return _virtualDataSources.ContainsKey(configId);
|
||||
}
|
||||
|
||||
public bool AddVirtualDataSource(IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
{
|
||||
if (!IsMultiShardingConfiguration&&_virtualDataSources.IsNotEmpty())
|
||||
throw new NotSupportedException("not support multi sharding configuration");
|
||||
var dataSource = new VirtualDataSource<TShardingDbContext>(_entityMetadataManager, _virtualDataSourceRouteManager, configurationParams);
|
||||
dataSource.CheckVirtualDataSource();
|
||||
return _virtualDataSources.TryAdd(dataSource.ConfigId, dataSource);
|
||||
}
|
||||
|
||||
public void SetDefaultIfMultiConfiguration()
|
||||
{
|
||||
if (IsMultiShardingConfiguration && ShardingConfigurationStrategy == ShardingConfigurationStrategyEnum.ReturnHighPriority)
|
||||
{
|
||||
var maxShardingConfiguration = _virtualDataSources.Values.OrderByDescending(o => o.Priority).FirstOrDefault();
|
||||
if (maxShardingConfiguration.ConfigId != _defaultConfigId)
|
||||
{
|
||||
_defaultConfigId = maxShardingConfiguration.ConfigId;
|
||||
_defaultVirtualDataSource = maxShardingConfiguration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IVirtualDataSource<TShardingDbContext> IVirtualDataSourceManager<TShardingDbContext>.GetCurrentVirtualDataSource()
|
||||
{
|
||||
return (IVirtualDataSource<TShardingDbContext>)GetCurrentVirtualDataSource();
|
||||
}
|
||||
|
||||
public List<IVirtualDataSource> GetAllVirtualDataSources()
|
||||
{
|
||||
if (!IsMultiShardingConfiguration)
|
||||
return new List<IVirtualDataSource>(1) { _defaultVirtualDataSource };
|
||||
return _virtualDataSources.Values.ToList();
|
||||
}
|
||||
|
||||
public VirtualDataSourceScope CreateScope(string configId)
|
||||
{
|
||||
var virtualDataSourceScope = new VirtualDataSourceScope(_virtualDataSourceAccessor);
|
||||
_virtualDataSourceAccessor.DataSourceContext = new VirtualDataSourceContext(configId);
|
||||
return virtualDataSourceScope;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,17 +16,10 @@ using ShardingCore.Sharding.Abstractions;
|
|||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceRouteManager<TShardingDbContext> : IVirtualDataSourceRouteManager<TShardingDbContext>
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class VirtualDataSourceRouteManager : IVirtualDataSourceRouteManager
|
||||
{
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly ConcurrentDictionary<Type, IVirtualDataSourceRoute> _dataSourceVirtualRoutes = new ConcurrentDictionary<Type, IVirtualDataSourceRoute>();
|
||||
|
||||
public VirtualDataSourceRouteManager(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
|
||||
public IVirtualDataSourceRoute<TEntity> GetRoute<TEntity>() where TEntity : class
|
||||
{
|
||||
return (IVirtualDataSourceRoute<TEntity>)GetRoute(typeof(TEntity));
|
||||
|
@ -34,9 +27,9 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
public IVirtualDataSourceRoute GetRoute(Type entityType)
|
||||
{
|
||||
if (!_entityMetadataManager.IsShardingDataSource(entityType))
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"entity type :[{entityType.FullName}] not configure sharding data source");
|
||||
// if (!_entityMetadataManager.IsShardingDataSource(entityType))
|
||||
// throw new ShardingCoreInvalidOperationException(
|
||||
// $"entity type :[{entityType.FullName}] not configure sharding data source");
|
||||
|
||||
if (!_dataSourceVirtualRoutes.TryGetValue(entityType, out var dataSourceVirtualRoute))
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
public class VirtualDataSourceScope:IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 分片配置访问器
|
||||
/// </summary>
|
||||
public IVirtualDataSourceAccessor VirtualDataSourceAccessor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="virtualDataSourceAccessor"></param>
|
||||
public VirtualDataSourceScope(IVirtualDataSourceAccessor virtualDataSourceAccessor)
|
||||
{
|
||||
VirtualDataSourceAccessor = virtualDataSourceAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
VirtualDataSourceAccessor.DataSourceContext = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
using ShardingCore.Utils;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.ShardingEnumerableQueries;
|
||||
using ShardingCore.Core.VirtualDatabase;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Sharding.EntityQueryConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.VirtualTables
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 18 December 2020 14:20:12
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 同数据库虚拟表
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class DefaultVirtualTable<T> : IVirtualTable<T> where T : class
|
||||
{
|
||||
public EntityMetadata EntityMetadata { get; }
|
||||
private readonly IVirtualTableRoute<T> _virtualTableRoute;
|
||||
|
||||
/// <summary>
|
||||
/// 分页配置
|
||||
/// </summary>
|
||||
public PaginationMetadata PaginationMetadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用智能分页
|
||||
/// </summary>
|
||||
public bool EnablePagination => PaginationMetadata != null;
|
||||
/// <summary>
|
||||
/// 查询配置
|
||||
/// </summary>
|
||||
public EntityQueryMetadata EntityQueryMetadata { get; }
|
||||
/// <summary>
|
||||
/// 是否启用表达式分片配置
|
||||
/// </summary>
|
||||
public bool EnableEntityQuery => EntityQueryMetadata != null;
|
||||
|
||||
|
||||
private readonly ConcurrentDictionary<IPhysicTable, object> _physicTables = new ConcurrentDictionary<IPhysicTable, object>();
|
||||
|
||||
public DefaultVirtualTable(IVirtualTableRoute<T> virtualTableRoute,EntityMetadata entityMetadata)
|
||||
{
|
||||
EntityMetadata = entityMetadata;
|
||||
_virtualTableRoute = virtualTableRoute;
|
||||
var paginationConfiguration = virtualTableRoute.CreatePaginationConfiguration();
|
||||
if (paginationConfiguration!=null)
|
||||
{
|
||||
PaginationMetadata = new PaginationMetadata();
|
||||
var paginationBuilder = new PaginationBuilder<T>(PaginationMetadata);
|
||||
paginationConfiguration.Configure(paginationBuilder);
|
||||
}
|
||||
|
||||
var entityQueryConfiguration = virtualTableRoute.CreateEntityQueryConfiguration();
|
||||
if (entityQueryConfiguration != null)
|
||||
{
|
||||
EntityQueryMetadata = new EntityQueryMetadata();
|
||||
var entityQueryBuilder = new EntityQueryBuilder<T>(EntityQueryMetadata);
|
||||
entityQueryConfiguration.Configure(entityQueryBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public List<IPhysicTable> GetAllPhysicTables()
|
||||
{
|
||||
return _physicTables.Keys.ToList();
|
||||
}
|
||||
|
||||
public List<IPhysicTable> RouteTo(ShardingTableRouteConfig tableRouteConfig)
|
||||
{
|
||||
var route = _virtualTableRoute;
|
||||
if (tableRouteConfig.UseQueryable())
|
||||
return route.RouteWithPredicate(GetAllPhysicTables(), tableRouteConfig.GetQueryable(), true);
|
||||
if (tableRouteConfig.UsePredicate())
|
||||
return route.RouteWithPredicate(GetAllPhysicTables(), new ShardingEmptyEnumerableQuery<T>((Expression<Func<T, bool>>)tableRouteConfig.GetPredicate()).EmptyQueryable(), false);
|
||||
object shardingKeyValue = null;
|
||||
if (tableRouteConfig.UseValue())
|
||||
shardingKeyValue = tableRouteConfig.GetShardingKeyValue();
|
||||
|
||||
if (tableRouteConfig.UseEntity())
|
||||
shardingKeyValue = tableRouteConfig.GetShardingEntity().GetPropertyValue(EntityMetadata.ShardingTableProperty.Name);
|
||||
|
||||
if (shardingKeyValue == null)
|
||||
throw new ShardingCoreException(" route entity queryable or sharding key value is null ");
|
||||
var routeWithValue = route.RouteWithValue(GetAllPhysicTables(), shardingKeyValue);
|
||||
return new List<IPhysicTable>(1) { routeWithValue };
|
||||
}
|
||||
|
||||
|
||||
public bool AddPhysicTable(IPhysicTable physicTable)
|
||||
{
|
||||
if (physicTable.EntityType != EntityMetadata.EntityType)
|
||||
throw new ShardingCoreInvalidOperationException($"virtual table entity type :[{EntityMetadata.EntityType.FullName}] physic table entity type:[{physicTable.EntityType.FullName}]");
|
||||
return _physicTables.TryAdd(physicTable, null);
|
||||
}
|
||||
|
||||
public string GetVirtualTableName()
|
||||
{
|
||||
return EntityMetadata.VirtualTableName;
|
||||
}
|
||||
|
||||
IVirtualTableRoute IVirtualTable.GetVirtualRoute()
|
||||
{
|
||||
return GetVirtualRoute();
|
||||
}
|
||||
|
||||
public List<string> GetTableAllTails()
|
||||
{
|
||||
return _physicTables.Keys.Select(o => o.Tail).ToList();
|
||||
}
|
||||
|
||||
public IVirtualTableRoute<T> GetVirtualRoute()
|
||||
{
|
||||
return _virtualTableRoute;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Bootstrappers;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualDatabase;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Sharding.EntityQueryConfigurations;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.VirtualTables
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:虚拟表在系统里面被映射为ef-core的表
|
||||
* @Date: Friday, 18 December 2020 14:06:31
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 虚拟表
|
||||
/// </summary>
|
||||
public interface IVirtualTable
|
||||
{
|
||||
EntityMetadata EntityMetadata { get; }
|
||||
/// <summary>
|
||||
/// 分页配置
|
||||
/// </summary>
|
||||
PaginationMetadata PaginationMetadata { get; }
|
||||
/// <summary>
|
||||
/// 是否启用分页配置
|
||||
/// </summary>
|
||||
bool EnablePagination { get; }
|
||||
/// <summary>
|
||||
/// 查询配置
|
||||
/// </summary>
|
||||
EntityQueryMetadata EntityQueryMetadata { get; }
|
||||
/// <summary>
|
||||
/// 是否启用表达式分片配置
|
||||
/// </summary>
|
||||
bool EnableEntityQuery { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的物理表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<IPhysicTable> GetAllPhysicTables();
|
||||
|
||||
/// <summary>
|
||||
/// 路由到具体的物理表 which physic table route
|
||||
/// </summary>
|
||||
/// <param name="tableRouteConfig"></param>
|
||||
/// <returns></returns>
|
||||
List<IPhysicTable> RouteTo(ShardingTableRouteConfig tableRouteConfig);
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic table
|
||||
/// </summary>
|
||||
/// <param name="physicTable"></param>
|
||||
/// <returns>添加成功</returns>
|
||||
bool AddPhysicTable(IPhysicTable physicTable);
|
||||
/// <summary>
|
||||
/// 获取原始表名 get original table name
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetVirtualTableName();
|
||||
/// <summary>
|
||||
/// 获取当前虚拟表的路由 get this virtual table route
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IVirtualTableRoute GetVirtualRoute();
|
||||
/// <summary>
|
||||
/// 获取启动时已经存在的表后缀 get this virtual table exists tails when app start
|
||||
/// <see cref="ShardingBootstrapper"/> CreateDateTables
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<string> GetTableAllTails();
|
||||
}
|
||||
|
||||
public interface IVirtualTable<T> : IVirtualTable where T : class
|
||||
{
|
||||
new IVirtualTableRoute<T> GetVirtualRoute();
|
||||
}
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualTables
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description: 用于管理虚拟表并且提供简单的操作方法api
|
||||
* @Date: Friday, 18 December 2020 14:10:03
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IVirtualTableManager
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 添加虚拟表应用启动时 add virtual table when app start
|
||||
/// </summary>
|
||||
/// <param name="virtualTable">虚拟表</param>
|
||||
bool AddVirtualTable(IVirtualTable virtualTable);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
/// </summary>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(Type shardingEntityType);
|
||||
/// <summary>
|
||||
/// 尝试获取虚拟表
|
||||
/// </summary>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable TryGetVirtualTable(Type shardingEntityType);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by actual table name
|
||||
/// </summary>
|
||||
/// <param name="virtualTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(string virtualTableName);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取虚拟表没有返回null
|
||||
/// </summary>
|
||||
/// <param name="virtualTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable TryGetVirtualTable(string virtualTableName);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的虚拟表 get all virtual table
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ISet<IVirtualTable> GetAllVirtualTables();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic table
|
||||
/// </summary>
|
||||
/// <param name="virtualTable"></param>
|
||||
/// <param name="physicTable"></param>
|
||||
bool AddPhysicTable(IVirtualTable virtualTable, IPhysicTable physicTable);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic table
|
||||
/// </summary>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <param name="physicTable"></param>
|
||||
bool AddPhysicTable(Type shardingEntityType, IPhysicTable physicTable);
|
||||
}
|
||||
/// <summary>
|
||||
/// 虚拟表管理者 virtual table manager
|
||||
/// </summary>
|
||||
public interface IVirtualTableManager<TShardingDbContext> : IVirtualTableManager where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,243 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualTables
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 18 December 2020 14:52:42
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 同一个数据库下的虚拟表管理者
|
||||
/// </summary>
|
||||
public class VirtualTableManager<TShardingDbContext> : IVirtualTableManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
|
||||
/// <summary>
|
||||
/// {entityType,virtualTableType}
|
||||
/// </summary>
|
||||
private readonly ConcurrentDictionary<Type, IVirtualTable> _shardingVirtualTables = new ConcurrentDictionary<Type, IVirtualTable>();
|
||||
private readonly ConcurrentDictionary<string, IVirtualTable> _shardingVirtualTaleVirtualTables = new ConcurrentDictionary<string, IVirtualTable>();
|
||||
public VirtualTableManager(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
|
||||
public bool AddVirtualTable(IVirtualTable virtualTable)
|
||||
{
|
||||
var result = _shardingVirtualTables.TryAdd(virtualTable.EntityMetadata.EntityType, virtualTable);
|
||||
_shardingVirtualTaleVirtualTables.TryAdd(virtualTable.GetVirtualTableName(), virtualTable);
|
||||
return result;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取对应的虚拟表
|
||||
/// </summary>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <returns></returns>
|
||||
public IVirtualTable GetVirtualTable(Type shardingEntityType)
|
||||
{
|
||||
if (!_entityMetadataManager.IsShardingTable(shardingEntityType))
|
||||
throw new ShardingCoreInvalidOperationException(shardingEntityType.FullName);
|
||||
if (!_shardingVirtualTables.TryGetValue(shardingEntityType, out var virtualTable))
|
||||
throw new ShardingCoreException($"virtual table not found entity: {shardingEntityType.FullName}");
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTable(Type shardingEntityType)
|
||||
{
|
||||
if (!_entityMetadataManager.IsShardingTable(shardingEntityType))
|
||||
throw new ShardingCoreInvalidOperationException(shardingEntityType.FullName);
|
||||
if (!_shardingVirtualTables.TryGetValue(shardingEntityType, out var virtualTable))
|
||||
return null;
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable(string virtualTableName)
|
||||
{
|
||||
if (!_shardingVirtualTaleVirtualTables.TryGetValue(virtualTableName, out var virtualTable))
|
||||
throw new ShardingCoreException($"virtual table not found virtual table name: {virtualTableName}");
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTable(string virtualTableName)
|
||||
{
|
||||
if (!_shardingVirtualTaleVirtualTables.TryGetValue(virtualTableName, out var virtualTable))
|
||||
return null;
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public ISet<IVirtualTable> GetAllVirtualTables()
|
||||
{
|
||||
return _shardingVirtualTables.Select(o => o.Value).ToHashSet();
|
||||
}
|
||||
|
||||
public bool AddPhysicTable(IVirtualTable virtualTable, IPhysicTable physicTable)
|
||||
{
|
||||
return AddPhysicTable(virtualTable.EntityMetadata.EntityType, physicTable);
|
||||
}
|
||||
|
||||
public bool AddPhysicTable(Type shardingEntityType, IPhysicTable physicTable)
|
||||
{
|
||||
if (!_shardingVirtualTables.TryGetValue(shardingEntityType, out var virtualTable))
|
||||
throw new ShardingCoreException($"virtual table not found entity: {shardingEntityType.FullName}");
|
||||
return virtualTable.AddPhysicTable(physicTable);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// {sharidngDbContextType:{entityType,virtualTableType}}
|
||||
///// </summary>
|
||||
//private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, IVirtualTable>> _shardingVirtualTables = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, IVirtualTable>>();
|
||||
//private readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, IVirtualTable>> _shardingVirtualTaleVirtualTables = new ConcurrentDictionary<Type, ConcurrentDictionary<string, IVirtualTable>>();
|
||||
//public VirtualTableManager()
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//private void CheckShardingDbContextType(Type shardingDbContextType)
|
||||
//{
|
||||
// if (!shardingDbContextType.IsShardingDbContext())
|
||||
// throw new ShardingCoreException(
|
||||
// $"{shardingDbContextType.FullName} must impl {nameof(IShardingDbContext)}");
|
||||
//}
|
||||
|
||||
//private void CheckShardingTableEntityType(Type shardingEntityType)
|
||||
//{
|
||||
// if (!shardingEntityType.IsShardingTable())
|
||||
// throw new ShardingCoreException(
|
||||
// $"{shardingEntityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
//}
|
||||
//private string CreateShardingEntityTypeKey(Type shardingDbContextType,Type entityType)
|
||||
//{
|
||||
// return $"{shardingDbContextType.FullName}{entityType.FullName}";
|
||||
//}
|
||||
//private string CreateShardingTableNameKey(Type shardingDbContextType,string originalTableName)
|
||||
//{
|
||||
// return $"{shardingDbContextType.FullName}{originalTableName}";
|
||||
//}
|
||||
|
||||
//public void AddVirtualTable(Type shardingDbContextType,IVirtualTable virtualTable)
|
||||
//{
|
||||
// CheckShardingDbContextType(shardingDbContextType);
|
||||
|
||||
// var innerShardingVirtualTables = _shardingVirtualTables.GetOrAdd(shardingDbContextType,
|
||||
// key => new ConcurrentDictionary<Type, IVirtualTable>());
|
||||
|
||||
// if (!innerShardingVirtualTables.ContainsKey(virtualTable.EntityType))
|
||||
// {
|
||||
// innerShardingVirtualTables.TryAdd(virtualTable.EntityType, virtualTable);
|
||||
// }
|
||||
|
||||
// var innerShardingOriginalTableVirtualTables = _shardingVirtualTaleVirtualTables.GetOrAdd(shardingDbContextType,type=>new ConcurrentDictionary<string, IVirtualTable>());
|
||||
|
||||
// if (!innerShardingOriginalTableVirtualTables.ContainsKey(virtualTable.GetVirtualTableName()))
|
||||
// {
|
||||
// innerShardingOriginalTableVirtualTables.TryAdd(virtualTable.GetVirtualTableName(), virtualTable);
|
||||
// }
|
||||
//}
|
||||
|
||||
//public IVirtualTable GetVirtualTable(Type shardingDbContextType,Type shardingEntityType)
|
||||
//{
|
||||
// CheckShardingDbContextType(shardingDbContextType);
|
||||
// CheckShardingTableEntityType(shardingEntityType);
|
||||
|
||||
// var shardingKey = CreateShardingEntityTypeKey(shardingDbContextType, shardingEntityType);
|
||||
// if(!_shardingVirtualTables.TryGetValue(shardingDbContextType,out var innerShardingVirtualTables) || innerShardingVirtualTables.IsEmpty())
|
||||
// throw new ShardingVirtualTableNotFoundException(shardingDbContextType.FullName);
|
||||
|
||||
// if (!innerShardingVirtualTables.TryGetValue(shardingEntityType, out var virtualTable)||virtualTable==null)
|
||||
// throw new ShardingVirtualTableNotFoundException(shardingEntityType.FullName);
|
||||
// return virtualTable;
|
||||
//}
|
||||
|
||||
|
||||
//public IVirtualTable<T> GetVirtualTable<TDbContext, T>() where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// return (IVirtualTable<T>)GetVirtualTable(typeof(TDbContext), typeof(T));
|
||||
//}
|
||||
|
||||
//public IVirtualTable GetVirtualTable(Type shardingDbContextType, string originalTableName)
|
||||
//{
|
||||
// CheckShardingDbContextType(shardingDbContextType);
|
||||
// if (!_shardingVirtualTaleVirtualTables.TryGetValue(shardingDbContextType, out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
// throw new ShardingVirtualTableNotFoundException(shardingDbContextType.FullName);
|
||||
// if(!innerShardingOriginalTableVirtualTables.TryGetValue(originalTableName,out var virtualTable)|| virtualTable==null)
|
||||
// throw new ShardingVirtualTableNotFoundException(originalTableName);
|
||||
// return virtualTable;
|
||||
//}
|
||||
|
||||
//public IVirtualTable GetVirtualTable<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// return GetVirtualTable(typeof(TDbContext),originalTableName);
|
||||
//}
|
||||
|
||||
//public IVirtualTable TryGetVirtualTable(Type shardingDbContextType,string originalTableName)
|
||||
//{
|
||||
// CheckShardingDbContextType(shardingDbContextType);
|
||||
// if (!_shardingVirtualTaleVirtualTables.TryGetValue(shardingDbContextType,
|
||||
// out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
// return null;
|
||||
// if (!innerShardingOriginalTableVirtualTables.TryGetValue(originalTableName, out var virtualTable) || virtualTable == null)
|
||||
// return null;
|
||||
// return virtualTable;
|
||||
//}
|
||||
|
||||
//public IVirtualTable TryGetVirtualTablee<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// return TryGetVirtualTable(typeof(TDbContext), originalTableName);
|
||||
//}
|
||||
|
||||
|
||||
//public List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType)
|
||||
//{
|
||||
// if (!_shardingVirtualTaleVirtualTables.TryGetValue(shardingDbContextType,
|
||||
// out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
// return new List<IVirtualTable>();
|
||||
// var keyPrefix = shardingDbContextType.FullName;
|
||||
// return innerShardingOriginalTableVirtualTables.Values.ToList();
|
||||
//}
|
||||
|
||||
//public List<IVirtualTable> GetAllVirtualTables<TDbContext>() where TDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// return GetAllVirtualTables(typeof(TDbContext));
|
||||
//}
|
||||
|
||||
//public void AddPhysicTable(Type shardingDbContextType,IVirtualTable virtualTable, IPhysicTable physicTable)
|
||||
//{
|
||||
// AddPhysicTable(shardingDbContextType, virtualTable.EntityType, physicTable);
|
||||
//}
|
||||
|
||||
//public void AddPhysicTable<TDbContext>(IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// AddPhysicTable(typeof(TDbContext),virtualTable.EntityType, physicTable);
|
||||
//}
|
||||
|
||||
|
||||
//public void AddPhysicTable(Type shardingDbContextType,Type shardingEntityType, IPhysicTable physicTable)
|
||||
//{
|
||||
// var virtualTable = GetVirtualTable(shardingDbContextType,shardingEntityType);
|
||||
// virtualTable.AddPhysicTable(physicTable);
|
||||
//}
|
||||
|
||||
|
||||
//public void AddPhysicTable<TDbContext>(Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
//{
|
||||
// var virtualTable = GetVirtualTable(typeof(TDbContext),shardingEntityType);
|
||||
// virtualTable.AddPhysicTable(physicTable);
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.Abstractions
|
||||
{
|
||||
|
||||
public interface ITableRouteManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 实体对象是否存在分表路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
bool HasRoute(Type entityType);
|
||||
/// <summary>
|
||||
/// 获取实体对象的分表路由,如果没有将抛出异常
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ShardingCoreInvalidOperationException">如果没有找到对应的路由</exception>
|
||||
IVirtualTableRoute GetRoute(Type entityType);
|
||||
/// <summary>
|
||||
/// 获取所有的分表路由
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<IVirtualTableRoute> GetRoutes();
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ShardingCoreInvalidOperationException">如果当前路由的对象不是分表对象将抛出异常</exception>
|
||||
bool AddRoute(IVirtualTableRoute route);
|
||||
|
||||
/// <summary>
|
||||
/// 直接路由采用默认数据源
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <param name="shardingTableRouteConfig"></param>
|
||||
/// <returns></returns>
|
||||
List<TableRouteUnit> RouteTo(Type entityType,
|
||||
ShardingTableRouteConfig shardingTableRouteConfig);
|
||||
/// <summary>
|
||||
/// 根据数据源路由进行分片路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="shardingTableRouteConfig"></param>
|
||||
/// <returns></returns>
|
||||
List<TableRouteUnit> RouteTo(Type entityType,DataSourceRouteResult dataSourceRouteResult,
|
||||
ShardingTableRouteConfig shardingTableRouteConfig);
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
using System.Linq;
|
||||
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.Abstracttions
|
||||
{
|
||||
|
||||
// public interface IShardingRoute
|
||||
// {
|
||||
// ISqlRouteUnit RouteTo(IQueryable queryable);
|
||||
// }
|
||||
}
|
|
@ -1,10 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
|
@ -25,8 +22,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
public abstract class AbstractShardingFilterVirtualDataSourceRoute<TEntity, TKey> : AbstractVirtualDataSourceRoute<TEntity, TKey> where TEntity : class
|
||||
{
|
||||
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>RouteShardingProvider.GetRequiredService<IShardingRouteManager>().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
|
|
|
@ -2,9 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Utils;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
// {
|
||||
// if (EnableRouteParseCompileCache.HasValue)
|
||||
// return EnableRouteParseCompileCache.Value;
|
||||
// return EntityConfigOptions.EnableDataSourceRouteCompileCache.GetValueOrDefault();
|
||||
// return RouteConfigOptions.EnableDataSourceRouteCompileCache.GetValueOrDefault();
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
|
|
|
@ -5,6 +5,8 @@ using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
|||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.EntityQueryConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
||||
|
@ -19,7 +21,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
{
|
||||
public EntityMetadata EntityMetadata { get; private set; }
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
public IShardingEntityConfigOptions EntityConfigOptions { get; private set; }
|
||||
// public IShardingRouteConfigOptions RouteConfigOptions { get; private set; }
|
||||
|
||||
public new PaginationMetadata PaginationMetadata { get; protected set; }
|
||||
public bool EnablePagination => PaginationMetadata != null;
|
||||
|
@ -27,11 +29,15 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
//public new EntityQueryMetadata EntityQueryMetadata { get; protected set; }
|
||||
//public bool EnableEntityQuery => EnableEntityQuery != null;
|
||||
|
||||
public void Initialize(EntityMetadata entityMetadata)
|
||||
public IShardingProvider RouteShardingProvider { get; private set;}
|
||||
|
||||
public void Initialize(EntityMetadata entityMetadata,IShardingProvider shardingProvider)
|
||||
{
|
||||
if (!_doOnlyOnce.IsUnDo())
|
||||
throw new ShardingCoreInvalidOperationException("already init");
|
||||
EntityMetadata = entityMetadata;
|
||||
|
||||
// RouteConfigOptions = shardingProvider.GetService<IShardingRouteConfigOptions>();
|
||||
var paginationConfiguration = CreatePaginationConfiguration();
|
||||
if (paginationConfiguration != null)
|
||||
{
|
||||
|
@ -39,18 +45,13 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.Abstractions
|
|||
var paginationBuilder = new PaginationBuilder<TEntity>(PaginationMetadata);
|
||||
paginationConfiguration.Configure(paginationBuilder);
|
||||
}
|
||||
//var entityQueryConfiguration = CreateEntityQueryConfiguration();
|
||||
//if (entityQueryConfiguration != null)
|
||||
//{
|
||||
// EntityQueryMetadata = new EntityQueryMetadata();
|
||||
// var entityQueryBuilder= new EntityQueryBuilder<TEntity>(EntityQueryMetadata);
|
||||
// entityQueryConfiguration.Configure(entityQueryBuilder);
|
||||
//}
|
||||
|
||||
|
||||
EntityConfigOptions =
|
||||
ShardingContainer.GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
|
||||
// var entityQueryConfiguration = CreateEntityQueryConfiguration();
|
||||
// if (entityQueryConfiguration != null)
|
||||
// {
|
||||
// EntityQueryMetadata = new EntityQueryMetadata();
|
||||
// var entityQueryBuilder= new EntityQueryBuilder<TEntity>(EntityQueryMetadata);
|
||||
// entityQueryConfiguration.Configure(entityQueryBuilder);
|
||||
// }
|
||||
}
|
||||
public virtual IPaginationConfiguration<TEntity> CreatePaginationConfiguration()
|
||||
{
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
{
|
||||
IntersectDataSources = intersectDataSources;
|
||||
}
|
||||
public DataSourceRouteResult(string dataSource):this(new HashSet<string>(){dataSource})
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// 交集
|
||||
/// </summary>
|
||||
|
|
|
@ -19,11 +19,11 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DataSourceRouteRuleEngine<TShardingDbContext> : IDataSourceRouteRuleEngine<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class DataSourceRouteRuleEngine: IDataSourceRouteRuleEngine
|
||||
{
|
||||
private readonly IEntityMetadataManager<TShardingDbContext> _entityMetadataManager;
|
||||
private readonly IEntityMetadataManager _entityMetadataManager;
|
||||
|
||||
public DataSourceRouteRuleEngine(IEntityMetadataManager<TShardingDbContext> entityMetadataManager)
|
||||
public DataSourceRouteRuleEngine(IEntityMetadataManager entityMetadataManager)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
|
|
|
@ -18,14 +18,14 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
/// <summary>
|
||||
/// 分库路由引擎工程
|
||||
/// </summary>
|
||||
public class DataSourceRouteRuleEngineFactory<TShardingDbContext>: IDataSourceRouteRuleEngineFactory<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public class DataSourceRouteRuleEngineFactory: IDataSourceRouteRuleEngineFactory
|
||||
{
|
||||
private readonly IDataSourceRouteRuleEngine<TShardingDbContext> _dataSourceRouteRuleEngine;
|
||||
private readonly IDataSourceRouteRuleEngine _dataSourceRouteRuleEngine;
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="dataSourceRouteRuleEngine"></param>
|
||||
public DataSourceRouteRuleEngineFactory(IDataSourceRouteRuleEngine<TShardingDbContext> dataSourceRouteRuleEngine)
|
||||
public DataSourceRouteRuleEngineFactory(IDataSourceRouteRuleEngine dataSourceRouteRuleEngine)
|
||||
{
|
||||
_dataSourceRouteRuleEngine = dataSourceRouteRuleEngine;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,4 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
DataSourceRouteResult Route(DataSourceRouteRuleContext routeRuleContext);
|
||||
}
|
||||
|
||||
public interface IDataSourceRouteRuleEngine<TShardingDbContext> : IDataSourceRouteRuleEngine
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,4 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
|||
DataSourceRouteResult Route(IQueryable queryable, IShardingDbContext shardingDbContext, Dictionary<Type, IQueryable> queryEntities);
|
||||
//DataSourceRouteResult Route(DataSourceRouteRuleContext ruleContext);
|
||||
}
|
||||
public interface IDataSourceRouteRuleEngineFactory<TShardingDbContext> : IDataSourceRouteRuleEngineFactory
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
using System.Linq;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
|
@ -12,8 +14,15 @@ namespace ShardingCore.Core.VirtualRoutes
|
|||
* @Date: Sunday, 22 August 2021 14:58:58
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class RouteTailFactory:IRouteTailFactory
|
||||
public class RouteTailFactory : IRouteTailFactory
|
||||
{
|
||||
private readonly IEntityMetadataManager _entityMetadataManager;
|
||||
|
||||
public RouteTailFactory(IEntityMetadataManager entityMetadataManager)
|
||||
{
|
||||
_entityMetadataManager = entityMetadataManager;
|
||||
}
|
||||
|
||||
public IRouteTail Create(string tail)
|
||||
{
|
||||
return Create(tail, true);
|
||||
|
@ -33,7 +42,7 @@ namespace ShardingCore.Core.VirtualRoutes
|
|||
|
||||
public IRouteTail Create(TableRouteResult tableRouteResult)
|
||||
{
|
||||
return Create(tableRouteResult,true);
|
||||
return Create(tableRouteResult, true);
|
||||
}
|
||||
|
||||
public IRouteTail Create(TableRouteResult tableRouteResult, bool cache)
|
||||
|
@ -61,7 +70,10 @@ namespace ShardingCore.Core.VirtualRoutes
|
|||
return new NoCacheSingleQueryRouteTail(tableRouteResult);
|
||||
}
|
||||
}
|
||||
return new MultiQueryRouteTail(tableRouteResult);
|
||||
|
||||
var isShardingTableQuery = tableRouteResult.ReplaceTables.Select(o => o.EntityType)
|
||||
.Any(o => _entityMetadataManager.IsShardingTable(o));
|
||||
return new MultiQueryRouteTail(tableRouteResult, isShardingTableQuery);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes
|
||||
{
|
||||
public class ShardingRouteResult
|
||||
{
|
||||
public IReadOnlyList<ISqlRouteUnit> RouteUnits { get; }
|
||||
public bool IsCrossDataSource { get; }
|
||||
public bool IsCrossTable { get; }
|
||||
public bool ExistCrossTableTails { get; }
|
||||
public bool IsEmpty { get; }
|
||||
|
||||
public ShardingRouteResult(List<ISqlRouteUnit> routeUnits,bool isEmpty,bool isCrossDataSource,bool isCrossTable,bool existCrossTableTails)
|
||||
{
|
||||
var routeUnitGroup = routeUnits.GroupBy(o=>o.DataSourceName);
|
||||
RouteUnits = routeUnits;
|
||||
var count = routeUnitGroup.Count();
|
||||
IsEmpty =isEmpty;
|
||||
IsCrossDataSource = isCrossDataSource;
|
||||
IsCrossTable = isCrossTable;
|
||||
ExistCrossTableTails=existCrossTableTails;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Join(",", Environment.NewLine,RouteUnits.Select(o => o.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// _isCrossDataSource = _sqlRouteUnits.Length > 1;
|
||||
// _isCrossTable = _sqlRouteUnits.Any(o=>o.TableRouteResult.ReplaceTables.Count>1);
|
||||
// _existCrossTableTails =_sqlRouteUnits.Any(o=>o.TableRouteResult.HasDifferentTail);
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes
|
||||
{
|
||||
public sealed class TableRouteUnit
|
||||
{
|
||||
public TableRouteUnit(string dataSourceName, string tail,Type entityType)
|
||||
{
|
||||
DataSourceName = dataSourceName;
|
||||
Tail = tail;
|
||||
EntityType = entityType;
|
||||
}
|
||||
|
||||
public string DataSourceName { get; }
|
||||
public string Tail { get;}
|
||||
public Type EntityType { get; }
|
||||
|
||||
private bool Equals(TableRouteUnit other)
|
||||
{
|
||||
return DataSourceName == other.DataSourceName && Tail == other.Tail && Equals(EntityType, other.EntityType);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return ReferenceEquals(this, obj) || obj is TableRouteUnit other && Equals(other);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(DataSourceName, Tail, EntityType);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (DataSourceName != null ? DataSourceName.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Tail != null ? Tail.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (EntityType != null ? EntityType.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.QueryRouteManagers;
|
||||
using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
|
@ -26,8 +23,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
/// <typeparam name="TKey"></typeparam>
|
||||
public abstract class AbstractShardingFilterVirtualTableRoute<T, TKey> : AbstractVirtualTableRoute<T, TKey> where T : class
|
||||
{
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>
|
||||
ShardingContainer.GetService<IShardingRouteManager>().Current;
|
||||
public ShardingRouteContext CurrentShardingRouteContext =>RouteShardingProvider.GetRequiredService<IShardingRouteManager>().Current;
|
||||
/// <summary>
|
||||
/// 启用提示路由
|
||||
/// </summary>
|
||||
|
@ -36,12 +32,21 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
/// 启用断言路由
|
||||
/// </summary>
|
||||
protected virtual bool EnableAssertRoute => false;
|
||||
public override List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable,bool isQuery)
|
||||
|
||||
/// <summary>
|
||||
/// 路由是否忽略数据源
|
||||
/// </summary>
|
||||
protected virtual bool RouteIgnoreDataSource => true;
|
||||
/// <summary>
|
||||
/// 路由数据源和表后缀连接符
|
||||
/// </summary>
|
||||
protected virtual string RouteSeparator => ".";
|
||||
public override List<TableRouteUnit> RouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable,bool isQuery)
|
||||
{
|
||||
if (!isQuery)
|
||||
{
|
||||
//后拦截器
|
||||
return DoRouteWithPredicate(allPhysicTables, queryable);
|
||||
return DoRouteWithPredicate(dataSourceRouteResult, queryable);
|
||||
}
|
||||
//强制路由不经过断言
|
||||
if (EnableHintRoute)
|
||||
|
@ -50,47 +55,49 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
if (CurrentShardingRouteContext.TryGetMustTail<T>(out HashSet<string> mustTails) && mustTails.IsNotEmpty())
|
||||
{
|
||||
var physicTables = allPhysicTables.Where(o => mustTails.Contains(o.Tail)).ToList();
|
||||
if (physicTables.IsEmpty()||physicTables.Count!=mustTails.Count)
|
||||
var filterTails = GetTails().Where(o => mustTails.Contains(o)).ToList();
|
||||
if (filterTails.IsEmpty()||filterTails.Count!=mustTails.Count)
|
||||
throw new ShardingCoreException(
|
||||
$" sharding route must error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",mustTails)}]");
|
||||
return physicTables;
|
||||
var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new TableRouteUnit(dataSourceName,tail,typeof(T)))).ToList();
|
||||
return shardingRouteUnits;
|
||||
}
|
||||
|
||||
if (CurrentShardingRouteContext.TryGetHintTail<T>(out HashSet<string> hintTails) && hintTails.IsNotEmpty())
|
||||
{
|
||||
var physicTables = allPhysicTables.Where(o => hintTails.Contains(o.Tail)).ToList();
|
||||
if (physicTables.IsEmpty()||physicTables.Count!=hintTails.Count)
|
||||
var filterTails = GetTails().Where(o => hintTails.Contains(o)).ToList();
|
||||
if (filterTails.IsEmpty()||filterTails.Count!=hintTails.Count)
|
||||
throw new ShardingCoreException(
|
||||
$" sharding route hint error:[{EntityMetadata.EntityType.FullName}]-->[{string.Join(",",hintTails)}]");
|
||||
return GetFilterTableNames(allPhysicTables, physicTables);
|
||||
var shardingRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>filterTails.Select(tail=> new TableRouteUnit(dataSourceName,tail,typeof(T)))).ToList();
|
||||
return GetFilterTableTails(dataSourceRouteResult, shardingRouteUnits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var filterPhysicTables = DoRouteWithPredicate(allPhysicTables,queryable);
|
||||
return GetFilterTableNames(allPhysicTables, filterPhysicTables);
|
||||
var filterPhysicTables = DoRouteWithPredicate(dataSourceRouteResult,queryable);
|
||||
return GetFilterTableTails(dataSourceRouteResult, filterPhysicTables);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是调用全局过滤器还是调用内部断言
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="filterPhysicTables"></param>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="shardingRouteUnits"></param>
|
||||
/// <returns></returns>
|
||||
private List<IPhysicTable> GetFilterTableNames(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
||||
private List<TableRouteUnit> GetFilterTableTails(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
|
||||
{
|
||||
if (UseAssertRoute)
|
||||
{
|
||||
//最后处理断言
|
||||
ProcessAssertRoutes(allPhysicTables, filterPhysicTables);
|
||||
return filterPhysicTables;
|
||||
ProcessAssertRoutes(dataSourceRouteResult, shardingRouteUnits);
|
||||
return shardingRouteUnits;
|
||||
}
|
||||
else
|
||||
{
|
||||
//后拦截器
|
||||
return AfterPhysicTableFilter(allPhysicTables, filterPhysicTables);
|
||||
return AfterShardingRouteUnitFilter(dataSourceRouteResult, shardingRouteUnits);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +106,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
out ICollection<ITableRouteAssert> routeAsserts) &&
|
||||
routeAsserts.IsNotEmpty();
|
||||
|
||||
private void ProcessAssertRoutes(List<IPhysicTable> allPhysicTables,List<IPhysicTable> filterPhysicTables)
|
||||
private void ProcessAssertRoutes(DataSourceRouteResult dataSourceRouteResult,List<TableRouteUnit> shardingRouteUnits)
|
||||
{
|
||||
if (UseAssertRoute)
|
||||
{
|
||||
|
@ -107,24 +114,33 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
foreach (var routeAssert in routeAsserts)
|
||||
{
|
||||
routeAssert.Assert(allPhysicTables, filterPhysicTables);
|
||||
routeAssert.Assert(dataSourceRouteResult,GetTails(), shardingRouteUnits);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable);
|
||||
protected abstract List<TableRouteUnit> DoRouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 物理表过滤后
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables">所有的物理表</param>
|
||||
/// <param name="filterPhysicTables">过滤后的物理表</param>
|
||||
/// <param name="dataSourceRouteResult">所有的数据源</param>
|
||||
/// <param name="shardingRouteUnits">所有的物理表</param>
|
||||
/// <returns></returns>
|
||||
protected virtual List<IPhysicTable> AfterPhysicTableFilter(List<IPhysicTable> allPhysicTables, List<IPhysicTable> filterPhysicTables)
|
||||
protected virtual List<TableRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
|
||||
{
|
||||
return filterPhysicTables;
|
||||
return shardingRouteUnits;
|
||||
}
|
||||
|
||||
protected string FormatTableRouteWithDataSource(string dataSourceName, string tableTail)
|
||||
{
|
||||
if (RouteIgnoreDataSource)
|
||||
{
|
||||
return tableTail;
|
||||
}
|
||||
return $"{dataSourceName}{RouteSeparator}{tableTail}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Utils;
|
||||
|
@ -7,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
||||
{
|
||||
|
@ -18,16 +18,27 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
*/
|
||||
public abstract class AbstractShardingOperatorVirtualTableRoute<TEntity, TKey> : AbstractShardingFilterVirtualTableRoute<TEntity, TKey> where TEntity : class
|
||||
{
|
||||
protected override List<IPhysicTable> DoRouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
protected override List<TableRouteUnit> DoRouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable)
|
||||
{
|
||||
//获取路由后缀表达式
|
||||
var routeParseExpression = ShardingUtil.GetRouteParseExpression(queryable, EntityMetadata, GetRouteFilter,true);
|
||||
//表达式缓存编译
|
||||
// var filter =CachingCompile(routeParseExpression);
|
||||
var filter =routeParseExpression.GetRoutePredicate();
|
||||
//通过编译结果进行过滤
|
||||
var physicTables = allPhysicTables.Where(o => filter(o.Tail)).ToList();
|
||||
return physicTables;
|
||||
var sqlRouteUnits = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName=>
|
||||
GetTails()
|
||||
.Where(o=>filter(FormatTableRouteWithDataSource(dataSourceName,o)))
|
||||
.Select(tail=>new TableRouteUnit(dataSourceName,tail,typeof(TEntity)))
|
||||
).ToList();
|
||||
|
||||
return sqlRouteUnits;
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,19 +71,23 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
throw new NotImplementedException(shardingPropertyName);
|
||||
}
|
||||
|
||||
public override IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey)
|
||||
public override TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey)
|
||||
{
|
||||
if (dataSourceRouteResult.IntersectDataSources.Count !=1)
|
||||
{
|
||||
throw new ShardingCoreException($"more than one route match data source:{string.Join(",", dataSourceRouteResult.IntersectDataSources)}");
|
||||
}
|
||||
var shardingKeyToTail = ShardingKeyToTail(shardingKey);
|
||||
|
||||
var physicTables = allPhysicTables.Where(o => o.Tail== shardingKeyToTail).ToList();
|
||||
if (physicTables.IsEmpty())
|
||||
var filterTails = GetTails().Where(o => o== shardingKeyToTail).ToList();
|
||||
if (filterTails.IsEmpty())
|
||||
{
|
||||
throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", allPhysicTables.Select(o=>o.FullName))}]");
|
||||
throw new ShardingCoreException($"sharding key route not match {EntityMetadata.EntityType} -> [{EntityMetadata.ShardingTableProperty.Name}] ->【{shardingKey}】 all tails ->[{string.Join(",", filterTails)}]");
|
||||
}
|
||||
|
||||
if (physicTables.Count > 1)
|
||||
throw new ShardingCoreException($"more than one route match table:{string.Join(",", physicTables.Select(o => $"[{o.FullName}]"))}");
|
||||
return physicTables[0];
|
||||
if (filterTails.Count > 1)
|
||||
throw new ShardingCoreException($"more than one route match table:{string.Join(",", filterTails)}");
|
||||
return new TableRouteUnit(dataSourceRouteResult.IntersectDataSources.First(), filterTails[0],typeof(TEntity));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
// {
|
||||
// if (EnableRouteParseCompileCache.HasValue)
|
||||
// return EnableRouteParseCompileCache.Value;
|
||||
// return EntityConfigOptions.EnableTableRouteCompileCache.GetValueOrDefault();
|
||||
// return RouteConfigOptions.EnableTableRouteCompileCache.GetValueOrDefault();
|
||||
// }
|
||||
// /// <summary>
|
||||
// /// 对表达式进行缓存编译默认永久缓存单个参数表达式,且不包含orElse只包含单个AndAlso或者没有AndAlso的,
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.ShardingConfigurations.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.MergeEngines.ParallelControl;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.ServiceProviders;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.EntityQueryConfigurations;
|
||||
using ShardingCore.Sharding.MergeEngines.Common.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
||||
{
|
||||
|
@ -20,15 +23,36 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
{
|
||||
|
||||
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
|
||||
public IShardingEntityConfigOptions EntityConfigOptions { get; private set; }
|
||||
public virtual void Initialize(EntityMetadata entityMetadata)
|
||||
// public IShardingRouteConfigOptions RouteConfigOptions { get; private set; }
|
||||
|
||||
public PaginationMetadata PaginationMetadata { get; private set; }
|
||||
public bool EnablePagination =>PaginationMetadata != null;
|
||||
public EntityQueryMetadata EntityQueryMetadata { get; private set; }
|
||||
public bool EnableEntityQuery =>EntityQueryMetadata != null;
|
||||
public IShardingProvider RouteShardingProvider { get; private set;}
|
||||
|
||||
public virtual void Initialize(EntityMetadata entityMetadata,IShardingProvider shardingProvider)
|
||||
{
|
||||
if (!_doOnlyOnce.IsUnDo())
|
||||
throw new ShardingCoreInvalidOperationException("already init");
|
||||
RouteShardingProvider = shardingProvider;
|
||||
EntityMetadata = entityMetadata;
|
||||
// RouteConfigOptions =shardingProvider.GetService<IShardingRouteConfigOptions>();
|
||||
var paginationConfiguration = CreatePaginationConfiguration();
|
||||
if (paginationConfiguration!=null)
|
||||
{
|
||||
PaginationMetadata = new PaginationMetadata();
|
||||
var paginationBuilder = new PaginationBuilder<T>(PaginationMetadata);
|
||||
paginationConfiguration.Configure(paginationBuilder);
|
||||
}
|
||||
|
||||
EntityConfigOptions =
|
||||
ShardingContainer.GetRequiredShardingEntityConfigOption(entityMetadata.ShardingDbContextType);
|
||||
var entityQueryConfiguration = CreateEntityQueryConfiguration();
|
||||
if (entityQueryConfiguration != null)
|
||||
{
|
||||
EntityQueryMetadata = new EntityQueryMetadata();
|
||||
var entityQueryBuilder = new EntityQueryBuilder<T>(EntityQueryMetadata);
|
||||
entityQueryConfiguration.Configure(entityQueryBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,24 +68,24 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
|||
/// <summary>
|
||||
/// 根据表达式路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="isQuery"></param>
|
||||
/// <returns></returns>
|
||||
public abstract List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables, IQueryable queryable,bool isQuery);
|
||||
public abstract List<TableRouteUnit> RouteWithPredicate(DataSourceRouteResult dataSourceRouteResult, IQueryable queryable,bool isQuery);
|
||||
|
||||
/// <summary>
|
||||
/// 根据值路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
public abstract IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey);
|
||||
public abstract TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey);
|
||||
/// <summary>
|
||||
/// 返回数据库现有的尾巴
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract List<string> GetAllTails();
|
||||
public abstract List<string> GetTails();
|
||||
|
||||
/// <summary>
|
||||
/// 配置分表的一些信息
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions
|
||||
{
|
||||
/// <summary>
|
||||
/// 可以追加尾巴
|
||||
/// </summary>
|
||||
public interface ITailAppendable
|
||||
{
|
||||
/// <summary>
|
||||
/// 追加尾巴
|
||||
/// </summary>
|
||||
/// <param name="tail"></param>
|
||||
/// <returns>是否添加成功</returns>
|
||||
bool Append(string tail);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Sharding.EntityQueryConfigurations;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
||||
|
@ -25,25 +25,43 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
|
|||
/// <summary>
|
||||
/// 根据查询条件路由返回物理表
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <param name="isQuery"></param>
|
||||
/// <returns></returns>
|
||||
List<IPhysicTable> RouteWithPredicate(List<IPhysicTable> allPhysicTables,IQueryable queryable,bool isQuery);
|
||||
List<TableRouteUnit> RouteWithPredicate(DataSourceRouteResult dataSourceRouteResult,IQueryable queryable,bool isQuery);
|
||||
|
||||
/// <summary>
|
||||
/// 根据值进行路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicTables"></param>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="shardingKey"></param>
|
||||
/// <returns></returns>
|
||||
IPhysicTable RouteWithValue(List<IPhysicTable> allPhysicTables, object shardingKey);
|
||||
TableRouteUnit RouteWithValue(DataSourceRouteResult dataSourceRouteResult, object shardingKey);
|
||||
/// <summary>
|
||||
/// 获取所有的目前数据库存在的尾巴,仅启动时调用
|
||||
/// get all tails in the db
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<string> GetAllTails();
|
||||
List<string> GetTails();
|
||||
|
||||
/// <summary>
|
||||
/// 分页配置
|
||||
/// </summary>
|
||||
PaginationMetadata PaginationMetadata { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用智能分页
|
||||
/// </summary>
|
||||
bool EnablePagination {get; }// PaginationMetadata != null;
|
||||
/// <summary>
|
||||
/// 查询配置
|
||||
/// </summary>
|
||||
EntityQueryMetadata EntityQueryMetadata { get; }
|
||||
/// <summary>
|
||||
/// 是否启用表达式分片配置
|
||||
/// </summary>
|
||||
bool EnableEntityQuery { get; }
|
||||
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue