完善样例代码

This commit is contained in:
xuejiaming 2022-07-01 23:29:37 +08:00
parent 78cd5f23b1
commit d198d46cbc
32 changed files with 550 additions and 749 deletions

View File

@ -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)
// {
//
// }
// }
// }

View File

@ -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);
// }
//
// }
// }

View File

@ -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);
// }
// }
// }
// }

View File

@ -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();

View File

@ -26,8 +26,6 @@ namespace Sample.MySql.Controllers
[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();

View File

@ -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())

View File

@ -47,21 +47,13 @@ namespace Sample.MySql
{
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())).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
});
o.UseShardingTransaction((connection, builder) =>
{
builder.UseMySql(connection, new MySqlServerVersion(new Version())
// ,b=>b.EnableRetryOnFailure()
)
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseLoggerFactory(efLogger);
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;");
o.AddDefaultDataSource("ds0","server=127.0.0.1;port=3306;database=dbdbd0;userid=root;password=root;");
})
.Build(sp);
});
@ -111,21 +103,6 @@ namespace Sample.MySql
{
app.UseDeveloperExceptionPage();
}
// app.UseShardingCore();
//
//
// using (var serviceScope = app.ApplicationServices.CreateScope())
// {
// var defaultShardingDbContext = serviceScope.ServiceProvider.GetService<DefaultShardingDbContext>();
// }
//
// Console.WriteLine("------------------");
// using (var serviceScope = app.ApplicationServices.CreateScope())
// {
// var defaultShardingDbContext = serviceScope.ServiceProvider.GetService<DefaultShardingDbContext>();
// }
// Console.WriteLine("------------------");
app.UseRouting();
app.UseAuthorization();

View File

@ -5,21 +5,15 @@ 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.Sharding.ReadWriteConfigurations.Abstractions;
namespace Sample.SqlServer.Controllers
@ -36,39 +30,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()
{

View File

@ -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())

View File

@ -1,15 +1,16 @@
using Microsoft.EntityFrameworkCore;
using Sample.SqlServer.DbContexts;
using ShardingCore;
using ShardingCore.Core;
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);
}
}

View File

@ -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,17 +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();
}
}

View File

@ -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) =>
{

View File

@ -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; }
// }
// }

View File

@ -27,42 +27,31 @@ namespace ShardingCore.Bootstrappers
/// <summary>
/// 对象元数据初始化器
/// </summary>
/// <typeparam name="TShardingDbContext"></typeparam>
/// <typeparam name="TEntity"></typeparam>
public class EntityMetadataInitializer<TEntity>: IEntityMetadataInitializer where TEntity:class
{
private static readonly ILogger<EntityMetadataInitializer<TEntity>> _logger=InternalLoggerFactory.CreateLogger<EntityMetadataInitializer<TEntity>>();
// private const string QueryFilter = "QueryFilter";
// private readonly IEntityType _entityType;
// private readonly string _virtualTableName;
// private readonly Expression<Func<TEntity,bool>> _queryFilterExpression;
private readonly Type _shardingEntityType;
private readonly IShardingProvider _shardingProvider;
private readonly IShardingRouteConfigOptions _shardingRouteConfigOptions;
private readonly IVirtualDataSourceRouteManager _virtualDataSourceRouteManager;
private readonly ITableRouteManager _tableRouteManager;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IJobManager _jobManager;
public EntityMetadataInitializer(
IShardingProvider shardingProvider,
IShardingRouteConfigOptions shardingRouteConfigOptions,
IVirtualDataSourceRouteManager virtualDataSourceRouteManager,
ITableRouteManager tableRouteManager,
IEntityMetadataManager entityMetadataManager,
IJobManager jobManager
IEntityMetadataManager entityMetadataManager
)
{
_shardingEntityType = typeof(TEntity);
// _entityType = entityMetadataEnsureParams.EntityType;
// _virtualTableName = entityMetadataEnsureParams.VirtualTableName;
// _queryFilterExpression = entityMetadataEnsureParams.EntityType.GetAnnotations().FirstOrDefault(o=>o.Name== QueryFilter)?.Value as Expression<Func<TEntity, bool>>;
_shardingProvider = shardingProvider;
_shardingRouteConfigOptions = shardingRouteConfigOptions;
_virtualDataSourceRouteManager = virtualDataSourceRouteManager;
_tableRouteManager = tableRouteManager;
_entityMetadataManager = entityMetadataManager;
_jobManager = jobManager;
}
/// <summary>
/// 初始化
@ -117,10 +106,10 @@ namespace ShardingCore.Bootstrappers
//检测校验分表分库对象元数据
entityMetadata.CheckShardingTableMetadata();
//添加任务
if (virtualTableRoute is IJob routeJob && routeJob.AutoCreateTableByTime())
if (virtualTableRoute is IJob routeJob)
{
var jobEntry = JobEntryFactory.Create(routeJob);
_jobManager.AddJob(jobEntry);
_shardingProvider.GetRequiredService<IJobManager>().AddJob(jobEntry);
}
}
entityMetadata.CheckGenericMetadata();

View File

@ -7,13 +7,13 @@
namespace ShardingCore.Bootstrappers
{
/// <summary>
/// 主要的分表启动器
/// 主要的分表初始化器,不再需要手动调用,<code>IShardingRuntimeContext初始化的时候会调用</code>
/// </summary>
public interface IShardingBootstrapper
internal interface IShardingBootstrapper
{
/// <summary>
/// 启动
/// 初始化
/// </summary>
void Start();
void Initialize();
}
}

View File

@ -1,14 +1,19 @@
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.EntityMetadatas;
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
{
@ -18,31 +23,38 @@ namespace ShardingCore.Bootstrappers
* @Date: Monday, 21 December 2020 09:10:07
* @Email: 326308290@qq.com
*/
public class ShardingBootstrapper : IShardingBootstrapper
internal class ShardingBootstrapper : IShardingBootstrapper
{
private readonly ILogger<ShardingBootstrapper> _logger;
private readonly IShardingProvider _shardingProvider;
private readonly IShardingDbContextBootstrapper _shardingDbContextBootstrapper;
private readonly IShardingRouteConfigOptions _routeConfigOptions;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IParallelTableManager _parallelTableManager;
private readonly IJobManager _jobManager;
private readonly DoOnlyOnce _doOnlyOnce = new DoOnlyOnce();
public ShardingBootstrapper(IShardingProvider shardingProvider,IShardingDbContextBootstrapper shardingDbContextBootstrapper,IJobManager jobManager)
public ShardingBootstrapper(IShardingProvider shardingProvider)
{
_logger = InternalLoggerFactory.DefaultFactory.CreateLogger<ShardingBootstrapper>();
_shardingProvider = shardingProvider;
_shardingDbContextBootstrapper = shardingDbContextBootstrapper;
_jobManager = jobManager;
_routeConfigOptions = shardingProvider.GetRequiredService<IShardingRouteConfigOptions>();
_entityMetadataManager = shardingProvider.GetRequiredService<IEntityMetadataManager>();
_parallelTableManager = shardingProvider.GetRequiredService<IParallelTableManager>();
_jobManager = shardingProvider.GetRequiredService<IJobManager>();
}
/// <summary>
/// 启动
/// 初始化
/// </summary>
public void Start()
public void Initialize()
{
if (!_doOnlyOnce.IsUnDo())
return;
_logger.LogDebug("sharding core starting......");
_shardingDbContextBootstrapper.Initialize();
_logger.LogDebug("sharding core initialize entity metadata......");
InitializeEntityMetadata();
_logger.LogDebug("sharding core initialize parallel table......");
InitializeParallelTables();
_logger.LogDebug($"sharding core complete init");
if (_jobManager != null && _jobManager.HasAnyJob())
@ -54,6 +66,37 @@ namespace ShardingCore.Bootstrappers
}
_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);
}
}
}
}

View File

@ -1,115 +0,0 @@
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Core;
using ShardingCore.Core.EntityMetadatas;
using ShardingCore.Core.ShardingConfigurations.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
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 Initialize();
}
/// <summary>
/// 分片具体DbContext初始化器
/// </summary>
public class ShardingDbContextBootstrapper: IShardingDbContextBootstrapper
{
private readonly IShardingProvider _shardingProvider;
private readonly IShardingRouteConfigOptions _routeConfigOptions;
private readonly IEntityMetadataManager _entityMetadataManager;
private readonly IParallelTableManager _parallelTableManager;
public ShardingDbContextBootstrapper(
IShardingProvider shardingProvider,
IShardingRouteConfigOptions routeConfigOptions,
IEntityMetadataManager entityMetadataManager,
IParallelTableManager parallelTableManager
)
{
_shardingProvider = shardingProvider;
_routeConfigOptions = routeConfigOptions;
_entityMetadataManager = entityMetadataManager;
_parallelTableManager = parallelTableManager;
}
/// <summary>
/// 初始化
/// </summary>
public void Initialize()
{
InitializeEntityMetadata();
InitializeParallelTables();
// InitializeConfigure();
}
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);
}
}
// 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;
// _dataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName);
// }
// }
// }
}
}

View File

@ -6,5 +6,9 @@ namespace ShardingCore.Core
public interface IShardingProvider
{
object GetService(Type serviceType);
TService GetService<TService>();
object GetRequiredService(Type serviceType);
TService GetRequiredService<TService>();
}
}

View File

@ -9,77 +9,98 @@ using System.Data.Common;
namespace ShardingCore.Core.ShardingConfigurations.Abstractions
{
public interface IShardingRouteConfigOptions
{
/// <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>
/// 当查询遇到没有路由被命中时是否抛出错误
/// </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>
/// 添加分库路由
/// </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,6 +111,7 @@ namespace ShardingCore.Core.ShardingConfigurations.Abstractions
/// 平行表
/// </summary>
bool AddParallelTableGroupNode(ParallelTableGroupNode parallelTableGroupNode);
/// <summary>
/// 获取平行表
/// </summary>
@ -108,5 +130,7 @@ namespace ShardingCore.Core.ShardingConfigurations.Abstractions
//
// void UseExecutorDbContextConfigure(Action<DbContextOptionsBuilder> executorDbContextConfigure);
// void UseShellDbContextConfigure(Action<DbContextOptionsBuilder> shellDbContextConfigure);
}
}
}

View File

@ -1,132 +1,73 @@
// 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.Sharding.Abstractions;
// using ShardingCore.Sharding.ParallelTables;
//
// namespace ShardingCore.DIExtensions
// {
// /*
// * @Author: xjm
// * @Description:
// * @Date: 2021/9/19 20:49:03
// * @Ver: 1.0
// * @Email: 326308290@qq.com
// */
// public class ShardingCoreConfigBuilder<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
// {
// public IServiceCollection Services { get; }
//
//
// public List<ShardingConfigOptions> ShardingConfigOptions { get; }
// public ShardingRouteConfigOptions ShardingRouteConfigOptions { get; }
//
//
// public ShardingCoreConfigBuilder(IServiceCollection services)
// {
// Services = services;
// ShardingConfigOptions = new List<ShardingConfigOptions>();
// ShardingRouteConfigOptions = new ShardingRouteConfigOptions();
// }
//
// public ShardingConfigBuilder<TShardingDbContext> AddEntityConfig(Action<ShardingRouteConfigOptions> entityConfigure)
// {
// entityConfigure?.Invoke(ShardingRouteConfigOptions);
// return new ShardingConfigBuilder<TShardingDbContext>(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)
// {
// foreach (var entityType in entityTypes)
// {
// _createTableEntities.Add(entityType);
// }
//
// }
//
// public ISet<Type> GetCreateTableEntities()
// {
// return _createTableEntities;
// }
//
// public readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
//
// public bool AddParallelTables(params Type[] types)
// {
// 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))));
// }
// public ISet<ParallelTableGroupNode> GetParallelTableGroupNodes()
// {
// return _parallelTables;
// }
// }
// }
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Core.ShardingConfigurations.Abstractions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.ShardingConfigurations.ConfigBuilders
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 20:49:03
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingCoreConfigBuilder<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
private readonly IServiceCollection _services;
private readonly ShardingRuntimeBuilder<TShardingDbContext> _shardingRuntimeBuilder;
public ShardingCoreConfigBuilder(IServiceCollection services)
{
_services = services;
_shardingRuntimeBuilder = new ShardingRuntimeBuilder<TShardingDbContext>();
}
[Obsolete("plz use UseRouteConfig")]
public ShardingCoreConfigBuilder<TShardingDbContext> AddEntityConfig(Action<IShardingRouteConfigOptions> entityConfigure)
{
_shardingRuntimeBuilder.UseRouteConfig(entityConfigure);
return this;
}
public ShardingCoreConfigBuilder<TShardingDbContext> UseRouteConfig(Action<IShardingRouteConfigOptions> routeConfigure)
{
_shardingRuntimeBuilder.UseRouteConfig(routeConfigure);
return this;
}
public ShardingCoreConfigBuilder<TShardingDbContext> UseRouteConfig(Action<IShardingProvider,IShardingRouteConfigOptions> routeConfigure)
{
_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;
}
[Obsolete("plz use AddShardingCore")]
public void EnsureConfig()
{
_services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeBuilder.Build(sp));
}
public void AddShardingCore()
{
_services.AddSingleton<IShardingRuntimeContext>(sp => _shardingRuntimeBuilder.Build(sp));
}
}
}

View File

@ -151,6 +151,26 @@ namespace ShardingCore.Core.ShardingConfigurations
// throw new ArgumentNullException(nameof(tableEnsureManagerConfigure));
// }
public void CheckArguments()
{
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");
}
}
}

View File

@ -53,6 +53,15 @@ namespace ShardingCore.Core.ShardingConfigurations
public bool ThrowIfQueryRouteNotMatch { get; set; } = true;
/// <summary>
/// 添加分库路由
/// </summary>
/// <typeparam name="TRoute"></typeparam>
public void AddShardingDataSourceRoute<TRoute>() where TRoute : IVirtualDataSourceRoute
{
var routeType = typeof(TRoute);
AddShardingDataSourceRoute(routeType);
}
public void AddShardingDataSourceRoute(Type routeType)
{
if (!routeType.IsVirtualDataSourceRoute())
@ -71,6 +80,15 @@ namespace ShardingCore.Core.ShardingConfigurations
_virtualDataSourceRoutes.Add(shardingEntityType, routeType);
}
}
/// <summary>
/// 添加分表路由
/// </summary>
/// <typeparam name="TRoute"></typeparam>
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
{
var routeType = typeof(TRoute);
AddShardingTableRoute(routeType);
}
public void AddShardingTableRoute(Type routeType)
{
if (!routeType.IsIVirtualTableRoute())
@ -136,6 +154,7 @@ namespace ShardingCore.Core.ShardingConfigurations
{
return _parallelTables;
}
// /// <summary>
// /// 仅内部DbContext生效的配置委托
// /// </summary>
@ -156,5 +175,7 @@ namespace ShardingCore.Core.ShardingConfigurations
// {
// ShellDbContextConfigure = shellDbContextConfigure ?? throw new ArgumentNullException(nameof(shellDbContextConfigure));
// }
}
}

View File

@ -29,5 +29,24 @@ namespace ShardingCore.Core
}
return service;
}
public TService GetService<TService>()
{
return (TService)GetService(typeof(TService));
}
public object GetRequiredService(Type serviceType)
{
var service = GetService(serviceType);
if (service == null)
{
throw new ArgumentNullException($"cant resolve {serviceType.FullName}");
}
return service;
}
public TService GetRequiredService<TService>()
{
return (TService)GetRequiredService(typeof(TService));
}
}
}

View File

@ -56,7 +56,7 @@ namespace ShardingCore.Core
return;
isInited = true;
_serviceProvider = _serviceMap.BuildServiceProvider();
_serviceProvider.GetRequiredService<IShardingBootstrapper>().Start();
_serviceProvider.GetRequiredService<IShardingBootstrapper>().Initialize();
}
}

View File

@ -1,21 +0,0 @@
// using System;
// using System.Collections.Generic;
// using System.Diagnostics.CodeAnalysis;
// using System.Linq;
// using System.Text;
// using System.Threading.Tasks;
// using Microsoft.EntityFrameworkCore;
// using ShardingCore.DIExtensions;
// using ShardingCore.Sharding.Abstractions;
//
// namespace ShardingCore.Extensions
// {
// public static class ShardingCoreConfigBuilderExtension
// {
// [ExcludeFromCodeCoverage]
// public static void AddEntityTryCreateTable<TEntity>(this ShardingCoreBeginOptions source) where TEntity:class
// {
// source.AddEntitiesTryCreateTable(typeof(TEntity));
// }
// }
// }

View File

@ -33,25 +33,6 @@ namespace ShardingCore.Extensions
return Activator.CreateInstance(serviceType, @params);
}
public static object GetRequiredService(this IShardingProvider shardingProvider,Type serviceType)
{
var service = shardingProvider.GetService(serviceType);
if (service == null)
{
throw new ArgumentNullException($"cant resolve {serviceType.FullName}");
}
return service;
}
public static TService GetService<TService>(this IShardingProvider shardingProvider)
{
return (TService)shardingProvider.GetService(typeof(TService));
}
public static TService GetRequiredService<TService>(this IShardingProvider shardingProvider)
{
return (TService)shardingProvider.GetRequiredService(typeof(TService));
}
}
}

View File

@ -8,6 +8,5 @@ namespace ShardingCore.Jobs.Abstaractions
string JobName { get; }
string[] GetCronExpressions();
Task ExecuteAsync();
bool AutoCreateTableByTime();
}
}

View File

@ -11,7 +11,7 @@ namespace ShardingCore.Jobs.Abstaractions
* @Date: Wednesday, 06 January 2021 13:10:13
* @Email: 326308290@qq.com
*/
public interface IJobManager
internal interface IJobManager
{
void AddJob(JobEntry jobEntry);
bool HasAnyJob();

View File

@ -18,7 +18,6 @@ namespace ShardingCore.Jobs
[ExcludeFromCodeCoverage]
internal class JobRunnerService
{
private readonly IServiceProvider _serviceProvider;
private readonly IJobManager _jobManager;
private readonly ILogger<JobRunnerService> _logger;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
@ -29,9 +28,8 @@ namespace ShardingCore.Jobs
/// </summary>
private const long MAX_DELAY_MILLIS = 30000L;
public JobRunnerService(IServiceProvider serviceProvider,IJobManager jobManager, ILogger<JobRunnerService> logger)
public JobRunnerService(IJobManager jobManager, ILogger<JobRunnerService> logger)
{
_serviceProvider = serviceProvider;
_jobManager = jobManager;
_logger = logger;
}

View File

@ -29,6 +29,7 @@ using ShardingCore.Bootstrappers;
using ShardingCore.Core;
using ShardingCore.Core.DbContextCreator;
using ShardingCore.Core.QueryTrackers;
using ShardingCore.Core.ShardingConfigurations.ConfigBuilders;
using ShardingCore.Core.UnionAllMergeShardingProviders;
using ShardingCore.Core.UnionAllMergeShardingProviders.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
@ -55,34 +56,34 @@ namespace ShardingCore
*/
public static class ShardingCoreExtension
{
// /// <summary>
// /// 添加ShardingCore配置和EntityFrameworkCore的<![CDATA[services.AddDbContext<TShardingDbContext>]]>
// /// </summary>
// /// <typeparam name="TShardingDbContext"></typeparam>
// /// <param name="services"></param>
// /// <param name="contextLifetime"></param>
// /// <param name="optionsLifetime"></param>
// /// <returns></returns>
// /// <exception cref="NotSupportedException"></exception>
// public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingDbContext<TShardingDbContext>(this IServiceCollection services,
// ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
// ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
// where TShardingDbContext : DbContext, IShardingDbContext
// {
// if (contextLifetime == ServiceLifetime.Singleton)
// throw new NotSupportedException($"{nameof(contextLifetime)}:{nameof(ServiceLifetime.Singleton)}");
// if (optionsLifetime == ServiceLifetime.Singleton)
// throw new NotSupportedException($"{nameof(optionsLifetime)}:{nameof(ServiceLifetime.Singleton)}");
// services.AddDbContext<TShardingDbContext>(UseDefaultSharding<TShardingDbContext>, contextLifetime, optionsLifetime);
// return services.AddShardingConfigure<TShardingDbContext>();
// }
//
// public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingConfigure<TShardingDbContext>(this IServiceCollection services)
// where TShardingDbContext : DbContext, IShardingDbContext
// {
// //ShardingCoreHelper.CheckContextConstructors<TShardingDbContext>();
// return new ShardingCoreConfigBuilder<TShardingDbContext>(services);
// }
/// <summary>
/// 添加ShardingCore配置和EntityFrameworkCore的<![CDATA[services.AddDbContext<TShardingDbContext>]]>
/// </summary>
/// <typeparam name="TShardingDbContext"></typeparam>
/// <param name="services"></param>
/// <param name="contextLifetime"></param>
/// <param name="optionsLifetime"></param>
/// <returns></returns>
/// <exception cref="NotSupportedException"></exception>
public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingDbContext<TShardingDbContext>(this IServiceCollection services,
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
where TShardingDbContext : DbContext, IShardingDbContext
{
if (contextLifetime == ServiceLifetime.Singleton)
throw new NotSupportedException($"{nameof(contextLifetime)}:{nameof(ServiceLifetime.Singleton)}");
if (optionsLifetime == ServiceLifetime.Singleton)
throw new NotSupportedException($"{nameof(optionsLifetime)}:{nameof(ServiceLifetime.Singleton)}");
services.AddDbContext<TShardingDbContext>(UseDefaultSharding<TShardingDbContext>, contextLifetime, optionsLifetime);
return services.AddShardingConfigure<TShardingDbContext>();
}
public static ShardingCoreConfigBuilder<TShardingDbContext> AddShardingConfigure<TShardingDbContext>(this IServiceCollection services)
where TShardingDbContext : DbContext, IShardingDbContext
{
//ShardingCoreHelper.CheckContextConstructors<TShardingDbContext>();
return new ShardingCoreConfigBuilder<TShardingDbContext>(services);
}
public static void UseDefaultSharding<TShardingDbContext>(IServiceProvider serviceProvider,DbContextOptionsBuilder dbContextOptionsBuilder) where TShardingDbContext : DbContext, IShardingDbContext
{
@ -106,12 +107,12 @@ namespace ShardingCore
internal static IServiceCollection AddInternalShardingCore<TShardingDbContext>(this IServiceCollection services) where TShardingDbContext : DbContext, IShardingDbContext
{
services.TryAddSingleton<ITableRouteManager, TableRouteManager>();
services.TryAddSingleton<IShardingDbContextBootstrapper, ShardingDbContextBootstrapper>();
services.TryAddSingleton<IVirtualDataSourceConfigurationParams, SimpleVirtualDataSourceConfigurationParams>();
//分表dbcontext创建
services.TryAddSingleton<IDbContextCreator, ActivatorDbContextCreator<TShardingDbContext>>();
// services.TryAddSingleton<IDataSourceInitializer<TShardingDbContext>, DataSourceInitializer<TShardingDbContext>>();
services.TryAddSingleton<ITrackerManager, TrackerManager>();
services.TryAddSingleton<IStreamMergeContextFactory, StreamMergeContextFactory>();

View File

@ -11,44 +11,42 @@ namespace ShardingCore
{
public class ShardingRuntimeBuilder<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private IShardingRouteConfigOptions _shardingRouteConfigOptions = new ShardingRouteConfigOptions();
private ShardingConfigOptions _shardingConfigOptions = new ShardingConfigOptions();
public ShardingRuntimeBuilder()
{
}
private Action<IShardingProvider, IShardingRouteConfigOptions> _shardingRouteConfigOptionsConfigure;
public ShardingRuntimeBuilder<TShardingDbContext> UseRouteConfig(Action<IShardingRouteConfigOptions> configure)
{
if (configure == null)
throw new ArgumentNullException($"{nameof(configure)}");
configure.Invoke(_shardingRouteConfigOptions);
Action<IShardingProvider, IShardingRouteConfigOptions> fullConfigure = (sp, options) =>
{
configure.Invoke(options);
};
return UseRouteConfig(fullConfigure);
}
public ShardingRuntimeBuilder<TShardingDbContext> UseRouteConfig(Action<IShardingProvider,IShardingRouteConfigOptions> configure)
{
_shardingRouteConfigOptionsConfigure = configure ?? throw new ArgumentNullException($"{nameof(configure)}");
return this;
}
private Action<IShardingProvider, ShardingConfigOptions> _shardingConfigOptionsConfigure;
public ShardingRuntimeBuilder<TShardingDbContext> UseConfig(Action<ShardingConfigOptions> configure)
{
if (configure == null)
throw new ArgumentNullException($"{nameof(configure)}");
configure.Invoke(_shardingConfigOptions);
if (string.IsNullOrWhiteSpace(_shardingConfigOptions.DefaultDataSourceName))
throw new ArgumentNullException(
$"{nameof(_shardingConfigOptions.DefaultDataSourceName)} plz call {nameof(ShardingConfigOptions.AddDefaultDataSource)}");
if (string.IsNullOrWhiteSpace(_shardingConfigOptions.DefaultConnectionString))
throw new ArgumentNullException(
$"{nameof(_shardingConfigOptions.DefaultConnectionString)} plz call {nameof(ShardingConfigOptions.AddDefaultDataSource)}");
if (_shardingConfigOptions.ConnectionStringConfigure is null)
throw new ArgumentNullException($"plz call {nameof(_shardingConfigOptions.UseShardingQuery)}");
if (_shardingConfigOptions.ConnectionConfigure is null )
throw new ArgumentNullException(
$"plz call {nameof(_shardingConfigOptions.UseShardingTransaction)}");
if (_shardingConfigOptions.MaxQueryConnectionsLimit <= 0)
throw new ArgumentException(
$"{nameof(_shardingConfigOptions.MaxQueryConnectionsLimit)} should greater than and equal 1");
Action<IShardingProvider, ShardingConfigOptions> fullConfigure = (sp, options) =>
{
configure.Invoke(options);
};
return UseConfig(fullConfigure);
}
public ShardingRuntimeBuilder<TShardingDbContext> UseConfig(Action<IShardingProvider,ShardingConfigOptions> configure)
{
if (configure == null)
throw new ArgumentNullException($"{nameof(configure)}");
_shardingConfigOptionsConfigure = configure;
return this;
}
@ -68,9 +66,22 @@ namespace ShardingCore
shardingRuntimeContext.AddServiceConfig(services =>
{
// services.AddSingleton<IDbContextTypeCollector>(sp => new DbContextTypeCollector<TShardingDbContext>());
services.AddSingleton<IShardingRouteConfigOptions>(sp => _shardingRouteConfigOptions);
services.AddSingleton<IShardingRouteConfigOptions>(sp =>
{
var shardingProvider = sp.GetRequiredService<IShardingProvider>();
var shardingRouteConfigOptions = new ShardingRouteConfigOptions();
_shardingRouteConfigOptionsConfigure?.Invoke(shardingProvider,shardingRouteConfigOptions);
return shardingRouteConfigOptions;
});
services.AddSingleton(sp => _shardingConfigOptions);
services.AddSingleton(sp =>
{
var shardingProvider = sp.GetRequiredService<IShardingProvider>();
var shardingConfigOptions = new ShardingConfigOptions();
_shardingConfigOptionsConfigure?.Invoke(shardingProvider,shardingConfigOptions);
shardingConfigOptions.CheckArguments();
return shardingConfigOptions;
});
services.AddSingleton<IShardingProvider>(sp => new ShardingProvider(sp,appServiceProvider));
services.AddInternalShardingCore<TShardingDbContext>();
});

View File

@ -25,14 +25,11 @@ namespace ShardingCore.TableCreator
private static readonly ILogger<ShardingTableCreator> _logger =
InternalLoggerFactory.CreateLogger<ShardingTableCreator>();
private readonly IServiceProvider _serviceProvider;
private readonly IShardingRouteConfigOptions _routeConfigOptions;
private readonly IRouteTailFactory _routeTailFactory;
public ShardingTableCreator(IServiceProvider serviceProvider,
IShardingRouteConfigOptions routeConfigOptions, IRouteTailFactory routeTailFactory)
public ShardingTableCreator(IShardingRouteConfigOptions routeConfigOptions, IRouteTailFactory routeTailFactory)
{
_serviceProvider = serviceProvider;
_routeConfigOptions = routeConfigOptions;
_routeTailFactory = routeTailFactory;
}