完成了分表的支持除了批量处理 #10

This commit is contained in:
xuejiaming 2021-09-20 22:26:48 +08:00
parent a947a18b90
commit 18cdbfea0e
77 changed files with 1735 additions and 1013 deletions

View File

@ -29,6 +29,5 @@ namespace Sample.BulkConsole.DbContexts
entity.ToTable(nameof(Order));
});
}
public override Type ShardingDbContextType => this.GetType();
}
}

View File

@ -24,17 +24,14 @@ namespace Sample.BulkConsole
var services = new ServiceCollection();
services.AddLogging();
services.AddShardingDbContext<MyShardingDbContext, MyDbContext>(
o => o.UseSqlServer("Data Source=localhost;Initial Catalog=MyOrderSharding;Integrated Security=True;")
, op =>
{
op.EnsureCreatedWithOutShardingTable = true;
op.CreateShardingTableOnStart = true;
op.UseShardingOptionsBuilder(
(connection, builder) => builder.UseSqlServer(connection),//使用dbconnection创建dbcontext支持事务
(conStr, builder) => builder.UseSqlServer(conStr).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
);
o => o.UseSqlServer("Data Source=localhost;Initial Catalog=MyOrderSharding;Integrated Security=True;"))
.Begin(true)
.AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking))
.AddShardingTransaction((connection, builder) => builder.UseSqlServer(connection))
.AddDefaultDataSource("ds0", "Data Source=localhost;Initial Catalog=MyOrderSharding;Integrated Security=True;")
.AddShardingTable(op=> {
op.AddShardingTableRoute<OrderVirtualRoute>();
});
}).End();
var serviceProvider = services.BuildServiceProvider();
serviceProvider.GetService<IShardingBootstrapper>().Start();
using (var serviceScope = serviceProvider.CreateScope())

View File

@ -19,6 +19,5 @@ namespace Sample.MySql.DbContexts
modelBuilder.ApplyConfiguration(new SysUserLogByMonthMap());
}
public override Type ShardingDbContextType => this.GetType();
}
}

View File

@ -1,6 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Sample.MySql.Domain.Maps;
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Sharding.Abstractions;
namespace Sample.MySql.DbContexts

View File

@ -116,47 +116,47 @@ namespace Sample.SqlServer.Controllers
shardingPageResultAsync
});
}
[HttpGet]
public IActionResult Get3()
{
//[HttpGet]
//public IActionResult Get3()
//{
var dbContext2s = _defaultTableDbContext.BulkShardingExpression<SysUserMod>(o => o.Age > 100);
using (var tran = _defaultTableDbContext.Database.BeginTransaction())
{
dbContext2s.ForEach(dbContext =>
{
dbContext.Set<SysUserMod>().Where(o => o.Age > 100).Update(o => new SysUserMod()
{
AgeGroup = 1000
});
});
_defaultTableDbContext.SaveChanges();
tran.Commit();
}
var list = new List<SysUserMod>();
var dbContexts = _defaultTableDbContext.BulkShardingEnumerable(list);
// var dbContext2s = _defaultTableDbContext.BulkShardingExpression<SysUserMod>(o => o.Age > 100);
// using (var tran = _defaultTableDbContext.Database.BeginTransaction())
// {
// dbContext2s.ForEach(dbContext =>
// {
// dbContext.Set<SysUserMod>().Where(o => o.Age > 100).Update(o => new SysUserMod()
// {
// AgeGroup = 1000
// });
// });
// _defaultTableDbContext.SaveChanges();
// tran.Commit();
// }
// var list = new List<SysUserMod>();
// var dbContexts = _defaultTableDbContext.BulkShardingEnumerable(list);
using (var tran = _defaultTableDbContext.Database.BeginTransaction())
{
dbContexts.ForEach(kv =>
{
kv.Key.BulkInsert(kv.Value);
});
dbContexts.ForEach(kv =>
{
kv.Key.BulkDelete(kv.Value);
});
dbContexts.ForEach(kv =>
{
kv.Key.BulkUpdate(kv.Value);
});
_defaultTableDbContext.SaveChanges();
tran.Commit();
}
// using (var tran = _defaultTableDbContext.Database.BeginTransaction())
// {
// dbContexts.ForEach(kv =>
// {
// kv.Key.BulkInsert(kv.Value);
// });
// dbContexts.ForEach(kv =>
// {
// kv.Key.BulkDelete(kv.Value);
// });
// dbContexts.ForEach(kv =>
// {
// kv.Key.BulkUpdate(kv.Value);
// });
// _defaultTableDbContext.SaveChanges();
// tran.Commit();
// }
return Ok();
}
// return Ok();
//}
}
}

View File

@ -22,7 +22,6 @@ namespace Sample.SqlServer.DbContexts
modelBuilder.ApplyConfiguration(new SysTestMap());
modelBuilder.ApplyConfiguration(new SysUserSalaryMap());
}
public override Type ShardingDbContextType => this.GetType();
}
}

View File

@ -29,26 +29,41 @@ namespace Sample.SqlServer
services.AddControllers();
//services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx3;Integrated Security=True"));
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(
o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;")
, op =>
{
op.EnsureCreatedWithOutShardingTable = true;
op.CreateShardingTableOnStart = true;
op.UseShardingOptionsBuilder(
(connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),//使用dbconnection创建dbcontext支持事务
(conStr,builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
//.ReplaceService<IQueryTranslationPostprocessorFactory,SqlServer2008QueryTranslationPostprocessorFactory>()//支持sqlserver2008r2
);//使用链接字符串创建dbcontext
//op.UseReadWriteConfiguration(sp => new List<string>()
//{
// "Data Source=localhost;Initial Catalog=ShardingCoreDB1;Integrated Security=True;",
// "Data Source=localhost;Initial Catalog=ShardingCoreDB2;Integrated Security=True;"
//}, ReadStrategyEnum.Random);
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
});
o => o.UseSqlServer(
"Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;")
).Begin(true)
.AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger)
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking))
.AddShardingTransaction((connection, builder) =>
builder.UseSqlServer(connection).UseLoggerFactory(efLogger))
.AddDefaultDataSource("ds0",
"Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;")
.AddShardingTable(o =>
{
o.AddShardingTableRoute<SysUserModVirtualTableRoute>();
o.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
}).End();
//services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(
// o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;")
// , op =>
// {
// op.EnsureCreatedWithOutShardingTable = true;
// op.CreateShardingTableOnStart = true;
// op.UseShardingOptionsBuilder(
// (connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),//使用dbconnection创建dbcontext支持事务
// (conStr,builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
// //.ReplaceService<IQueryTranslationPostprocessorFactory,SqlServer2008QueryTranslationPostprocessorFactory>()//支持sqlserver2008r2
// );//使用链接字符串创建dbcontext
// //op.UseReadWriteConfiguration(sp => new List<string>()
// //{
// // "Data Source=localhost;Initial Catalog=ShardingCoreDB1;Integrated Security=True;",
// // "Data Source=localhost;Initial Catalog=ShardingCoreDB2;Integrated Security=True;"
// //}, ReadStrategyEnum.Random);
// op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
// op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
// });
}

View File

@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
{
@ -16,16 +18,16 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
/// <summary>
/// 虚拟数据源 连接所有的实际数据源
/// </summary>
public interface IVirtualDataSource
public interface IVirtualDataSource<TShardingDbContext>
where TShardingDbContext : DbContext, IShardingDbContext
{
Type ShardingDbContextType{get; }
string DefaultDataSourceName { get; }
/// <summary>
/// 路由到具体的物理数据源
/// </summary>
/// <returns>data source names</returns>
List<string> RouteTo(Type entityType,ShardingDataSourceRouteConfig routeRouteConfig);
List<string> RouteTo(Type entityType, ShardingDataSourceRouteConfig routeRouteConfig);
/// <summary>
/// 获取当前数据源的路由
@ -49,5 +51,6 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
/// <returns>是否添加成功</returns>
bool AddPhysicDataSource(IPhysicDataSource physicDataSource);
bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute);
}
}

View File

@ -1,35 +1,35 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Sharding.Abstractions;
//using System;
//using System.Collections.Generic;
//using Microsoft.EntityFrameworkCore;
//using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
//using ShardingCore.Core.VirtualRoutes;
//using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
{
/*
* @Author: xjm
* @Description:
* @Date: Saturday, 06 February 2021 14:24:01
* @Email: 326308290@qq.com
*/
public interface IVirtualDataSourceManager
{
/// <summary>
/// 添加链接
/// </summary>
/// <param name="physicDataSource"></param>
bool AddPhysicDataSource(IPhysicDataSource physicDataSource);
IVirtualDataSource GetVirtualDataSource();
IPhysicDataSource GetDefaultDataSource();
string GetDefaultDataSourceName();
IPhysicDataSource GetPhysicDataSource(string dataSourceName);
}
public interface IVirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager where TShardingDbContext : DbContext, IShardingDbContext
{
//namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
//{
// /*
// * @Author: xjm
// * @Description:
// * @Date: Saturday, 06 February 2021 14:24:01
// * @Email: 326308290@qq.com
// */
// public interface IVirtualDataSourceManager
// {
// /// <summary>
// /// 添加链接
// /// </summary>
// /// <param name="physicDataSource"></param>
// bool AddPhysicDataSource(IPhysicDataSource physicDataSource);
// IVirtualDataSource GetVirtualDataSource();
// IPhysicDataSource GetDefaultDataSource();
// string GetDefaultDataSourceName();
// IPhysicDataSource GetPhysicDataSource(string dataSourceName);
// }
// public interface IVirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager where TShardingDbContext : DbContext, IShardingDbContext
// {
}
}
// }
//}

View File

@ -3,11 +3,13 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Utils;
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
@ -18,21 +20,15 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
* @Date: Friday, 05 February 2021 15:21:04
* @Email: 326308290@qq.com
*/
public class VirtualDataSource : IVirtualDataSource
public class VirtualDataSource<TShardingDbContext> : IVirtualDataSource<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly ConcurrentDictionary<Type, IVirtualDataSourceRoute> _dataSourceVirtualRoutes = new ConcurrentDictionary<Type, IVirtualDataSourceRoute>();
private readonly ConcurrentDictionary<string, IPhysicDataSource> _physicDataSources =
new ConcurrentDictionary<string, IPhysicDataSource>();
public string DefaultDataSourceName { get; }
public Type ShardingDbContextType { get; }
public string DefaultDataSourceName { get; private set; }
public VirtualDataSource(Type shardingDbContextType,string defaultDataSourceName)
{
ShardingDbContextType = shardingDbContextType;
DefaultDataSourceName = defaultDataSourceName??throw new ArgumentNullException(nameof(defaultDataSourceName));
}
@ -93,9 +89,24 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
public bool AddPhysicDataSource(IPhysicDataSource physicDataSource)
{
if (physicDataSource.IsDefault && physicDataSource.DataSourceName != DefaultDataSourceName)
throw new InvalidOperationException($"default data source name:[{DefaultDataSourceName}],add physic default data source name:[{physicDataSource.DataSourceName}]");
if (physicDataSource.IsDefault)
{
if (!string.IsNullOrWhiteSpace(DefaultDataSourceName))
{
throw new InvalidOperationException($"default data source name:[{DefaultDataSourceName}],add physic default data source name:[{physicDataSource.DataSourceName}]");
}
DefaultDataSourceName = physicDataSource.DataSourceName;
}
return _physicDataSources.TryAdd(physicDataSource.DataSourceName, physicDataSource);
}
public bool AddVirtualDataSourceRoute(IVirtualDataSourceRoute virtualDataSourceRoute)
{
if (!virtualDataSourceRoute.EntityType.IsShardingDataSource())
throw new InvalidOperationException($"{virtualDataSourceRoute.EntityType.FullName} should impl {nameof(IShardingDataSource)}");
return _dataSourceVirtualRoutes.TryAdd(virtualDataSourceRoute.EntityType, virtualDataSourceRoute);
}
}
}

View File

@ -1,72 +1,74 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualRoutes;
//using System;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.Linq;
//using Microsoft.EntityFrameworkCore;
//using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
//using ShardingCore.Core.VirtualRoutes;
//using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
{
/*
* @Author: xjm
* @Description:
* @Date: Saturday, 06 February 2021 15:24:08
* @Email: 326308290@qq.com
*/
public class VirtualDataSourceManager : IVirtualDataSourceManager
{
private readonly IServiceProvider _serviceProvider;
/// <summary>
/// {sharding db context type :{entity type:virtual data source}}
/// </summary>
private readonly ConcurrentDictionary<Type, IVirtualDataSource> _virtualDataSources = new ConcurrentDictionary<Type, IVirtualDataSource>();
//namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
//{
// /*
// * @Author: xjm
// * @Description:
// * @Date: Saturday, 06 February 2021 15:24:08
// * @Email: 326308290@qq.com
// */
// public class VirtualDataSourceManager<TShardingDbContext> : IVirtualDataSourceManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
// {
// private readonly IServiceProvider _serviceProvider;
// /// <summary>
// /// {sharding db context type :{entity type:virtual data source}}
// /// </summary>
// private readonly ConcurrentDictionary<Type, IVirtualDataSource> _virtualDataSources = new ConcurrentDictionary<Type, IVirtualDataSource>();
public VirtualDataSourceManager(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
//var shardingEntities = AssemblyHelper.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes())
// .Where(type => !String.IsNullOrEmpty(type.Namespace))
// .Where(type => !type.IsAbstract&&type.GetInterfaces()
// .Any(it => it.IsInterface &&typeof(IShardingDataSource)==it)
// );
//foreach (var shardingEntity in shardingEntities)
//{
// Type genericType = typeof(IVirtualDataSource<>);
// Type interfaceType = genericType.MakeGenericType(shardingEntity);
// var virtualDataSource = (IVirtualDataSource)serviceProvider.GetService(interfaceType);
// _virtualDataSources.TryAdd(virtualDataSource.EntityType, virtualDataSource);
//}
}
// public VirtualDataSourceManager(IServiceProvider serviceProvider)
// {
// _serviceProvider = serviceProvider;
// //var shardingEntities = AssemblyHelper.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes())
// // .Where(type => !String.IsNullOrEmpty(type.Namespace))
// // .Where(type => !type.IsAbstract&&type.GetInterfaces()
// // .Any(it => it.IsInterface &&typeof(IShardingDataSource)==it)
// // );
// //foreach (var shardingEntity in shardingEntities)
// //{
// // Type genericType = typeof(IVirtualDataSource<>);
// // Type interfaceType = genericType.MakeGenericType(shardingEntity);
// // var virtualDataSource = (IVirtualDataSource)serviceProvider.GetService(interfaceType);
// // _virtualDataSources.TryAdd(virtualDataSource.EntityType, virtualDataSource);
// //}
// }
public bool AddPhysicDataSource(Type shardingDbContextType, IPhysicDataSource physicDataSource)
{
throw new NotImplementedException();
}
// public bool AddPhysicDataSource(IPhysicDataSource physicDataSource)
// {
// throw new NotImplementedException();
// }
public IVirtualDataSource GetVirtualDataSource(Type shardingDbContextType)
{
if (!_virtualDataSources.TryGetValue(shardingDbContextType, out var virtualDataSource))
throw new InvalidOperationException($"not found virtual data source sharding db context type:[{shardingDbContextType.FullName}]");
return virtualDataSource;
}
// public IVirtualDataSource GetVirtualDataSource()
// {
// if (!_virtualDataSources.TryGetValue(shardingDbContextType, out var virtualDataSource))
// throw new InvalidOperationException($"not found virtual data source sharding db context type:[{shardingDbContextType.FullName}]");
// return virtualDataSource;
// }
public IPhysicDataSource GetDefaultDataSource(Type shardingDbContextType)
{
var virtualDataSource = GetVirtualDataSource(shardingDbContextType);
return virtualDataSource.GetDefaultDataSource();
}
// public IPhysicDataSource GetDefaultDataSource()
// {
// var virtualDataSource = GetVirtualDataSource(shardingDbContextType);
// return virtualDataSource.GetDefaultDataSource();
// }
public string GetDefaultDataSourceName(Type shardingDbContextType)
{
var virtualDataSource = GetVirtualDataSource(shardingDbContextType);
return virtualDataSource.DefaultDataSourceName;
}
// public string GetDefaultDataSourceName()
// {
// var virtualDataSource = GetVirtualDataSource(shardingDbContextType);
// return virtualDataSource.DefaultDataSourceName;
// }
public IPhysicDataSource GetPhysicDataSource(Type shardingDbContextType, string dataSourceName)
{
throw new NotImplementedException();
}
}
}
// public IPhysicDataSource GetPhysicDataSource(string dataSourceName)
// {
// throw new NotImplementedException();
// }
// }
//}

View File

@ -20,7 +20,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualTables
/// <summary>
/// 同一个数据库下的虚拟表管理者
/// </summary>
public class DefaultVirtualTableManager<TShardingDbContext> : IVirtualTableManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
public class VirtualTableManager<TShardingDbContext> : IVirtualTableManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
/// <summary>
@ -98,7 +98,7 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualTables
///// </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 DefaultVirtualTableManager()
//public VirtualTableManager()
//{
//}

View File

@ -14,6 +14,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes
public interface IVirtualDataSourceRoute
{
Type EntityType { get; }
string ShardingKeyToDataSourceName(object shardingKeyValue);
/// <summary>
/// 根据查询条件路由返回物理数据源

View File

@ -18,29 +18,21 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class DataSourceRouteRuleEngine : IDataSourceRouteRuleEngine
public class DataSourceRouteRuleEngine<TShardingDbContext> : IDataSourceRouteRuleEngine<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly IVirtualDataSourceManager _virtualDataSourceManager;
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
public DataSourceRouteRuleEngine(IVirtualDataSourceManager virtualDataSourceManager)
public DataSourceRouteRuleEngine(IVirtualDataSource<TShardingDbContext> virtualDataSource)
{
_virtualDataSourceManager = virtualDataSourceManager;
_virtualDataSource = virtualDataSource;
}
public DataSourceRouteResult Route<T, TShardingDbContext>(DataSourceRouteRuleContext<T> routeRuleContext) where TShardingDbContext : DbContext, IShardingDbContext
public DataSourceRouteResult Route<T>(DataSourceRouteRuleContext<T> routeRuleContext)
{
return this.Route<T>(typeof(TShardingDbContext), routeRuleContext);
}
public DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> routeRuleContext)
{
if (!shardingDbContextType.IsShardingDataSource())
throw new InvalidOperationException($"{shardingDbContextType} must impl {nameof(IShardingDbContext)}");
var dataSourceMaps = new Dictionary<Type, ISet<string>>();
var notShardingDataSourceEntityType = routeRuleContext.QueryEntities.FirstOrDefault(o => !o.IsShardingDataSource());
//存在不分表的
if (notShardingDataSourceEntityType != null)
dataSourceMaps.Add(notShardingDataSourceEntityType, new HashSet<string>() { _virtualDataSourceManager.GetDefaultDataSourceName(shardingDbContextType) });
dataSourceMaps.Add(notShardingDataSourceEntityType, new HashSet<string>() { _virtualDataSource.DefaultDataSourceName });
var queryEntities = routeRuleContext.QueryEntities.Where(o => o.IsShardingDataSource()).ToList();
@ -48,8 +40,7 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
throw new ShardingCoreNotSupportedException($"{routeRuleContext.Queryable.ShardingPrint()}");
foreach (var queryEntity in queryEntities)
{
var virtualDataSource = _virtualDataSourceManager.GetVirtualDataSource(shardingDbContextType);
var dataSourceConfigs = virtualDataSource.RouteTo(queryEntity,new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
var dataSourceConfigs = _virtualDataSource.RouteTo(queryEntity,new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
if (!dataSourceMaps.ContainsKey(queryEntity))
{
dataSourceMaps.Add(queryEntity, dataSourceConfigs.ToHashSet());

View File

@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
{
@ -15,14 +17,14 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
/// <summary>
/// 分库路由引擎工程
/// </summary>
public class DataSourceRouteRuleEngineFactory: IDataSourceRouteRuleEngineFactory
public class DataSourceRouteRuleEngineFactory<TShardingDbContext>: IDataSourceRouteRuleEngineFactory<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly IDataSourceRouteRuleEngine _dataSourceRouteRuleEngine;
private readonly IDataSourceRouteRuleEngine<TShardingDbContext> _dataSourceRouteRuleEngine;
/// <summary>
/// ctor
/// </summary>
/// <param name="dataSourceRouteRuleEngine"></param>
public DataSourceRouteRuleEngineFactory(IDataSourceRouteRuleEngine dataSourceRouteRuleEngine)
public DataSourceRouteRuleEngineFactory(IDataSourceRouteRuleEngine<TShardingDbContext> dataSourceRouteRuleEngine)
{
_dataSourceRouteRuleEngine = dataSourceRouteRuleEngine;
}
@ -40,24 +42,22 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
/// 路由到具体的物理数据源
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="shardingDbContextType"></param>
/// <param name="queryable"></param>
/// <returns></returns>
public DataSourceRouteResult Route<T>(Type shardingDbContextType, IQueryable<T> queryable)
public DataSourceRouteResult Route<T>(IQueryable<T> queryable)
{
var ruleContext = CreateContext<T>(queryable);
return _dataSourceRouteRuleEngine.Route(shardingDbContextType,ruleContext);
return _dataSourceRouteRuleEngine.Route(ruleContext);
}
/// <summary>
/// 路由到具体的物理数据源
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="shardingDbContextType"></param>
/// <param name="ruleContext"></param>
/// <returns></returns>
public DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> ruleContext)
public DataSourceRouteResult Route<T>(DataSourceRouteRuleContext<T> ruleContext)
{
return _dataSourceRouteRuleEngine.Route(shardingDbContextType, ruleContext);
return _dataSourceRouteRuleEngine.Route(ruleContext);
}
}
}

View File

@ -15,7 +15,12 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
*/
public interface IDataSourceRouteRuleEngine
{
DataSourceRouteResult Route<T,TShardingDbContext>(DataSourceRouteRuleContext<T> routeRuleContext) where TShardingDbContext:DbContext,IShardingDbContext;
DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> routeRuleContext);
DataSourceRouteResult Route<T>(DataSourceRouteRuleContext<T> routeRuleContext);
}
public interface IDataSourceRouteRuleEngine<TShardingDbContext> : IDataSourceRouteRuleEngine
where TShardingDbContext : DbContext, IShardingDbContext
{
}
}

View File

@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
{
@ -12,10 +14,12 @@ namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public interface IDataSourceRouteRuleEngineFactory
public interface IDataSourceRouteRuleEngineFactory<TShardingDbContext>
where TShardingDbContext : DbContext, IShardingDbContext
{
DataSourceRouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
DataSourceRouteResult Route<T>(Type shardingDbContextType, IQueryable<T> queryable);
DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> ruleContext);
DataSourceRouteResult Route<T>(IQueryable<T> queryable);
DataSourceRouteResult Route<T>(DataSourceRouteRuleContext<T> ruleContext);
}
}

View File

@ -11,9 +11,10 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
* @Date: Thursday, 28 January 2021 10:25:22
* @Email: 326308290@qq.com
*/
public interface ITableRouteRuleEngine
public interface ITableRouteRuleEngine<TShardingDbContext>
where TShardingDbContext : DbContext, IShardingDbContext
{
IEnumerable<TableRouteResult> Route<T,TShardingDbContext>(TableRouteRuleContext<T> tableRouteRuleContext) where TShardingDbContext:DbContext,IShardingDbContext;
IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType,TableRouteRuleContext<T> tableRouteRuleContext);
IEnumerable<TableRouteResult> Route<T>(TableRouteRuleContext<T> tableRouteRuleContext);
}
}

View File

@ -12,10 +12,11 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
* @Date: Thursday, 28 January 2021 13:30:28
* @Email: 326308290@qq.com
*/
public interface ITableRouteRuleEngineFactory
public interface ITableRouteRuleEngineFactory<TShardingDbContext>
where TShardingDbContext : DbContext, IShardingDbContext
{
TableRouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType,IQueryable<T> queryable);
IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, TableRouteRuleContext<T> ruleContext);
IEnumerable<TableRouteResult> Route<T>(IQueryable<T> queryable);
IEnumerable<TableRouteResult> Route<T>(TableRouteRuleContext<T> ruleContext);
}
}

View File

@ -12,12 +12,10 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
*/
public class TableRouteRuleContext<T>
{
private readonly IVirtualTableManager _virtualTableManager;
public TableRouteRuleContext(IQueryable<T> queryable, IVirtualTableManager virtualTableManager)
public TableRouteRuleContext(IQueryable<T> queryable)
{
Queryable = queryable;
_virtualTableManager = virtualTableManager;
}
public IQueryable<T> Queryable { get; }

View File

@ -21,78 +21,16 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
* @Date: Thursday, 28 January 2021 10:51:59
* @Email: 326308290@qq.com
*/
public class TableRouteRuleEngines:ITableRouteRuleEngine
public class TableRouteRuleEngine<TShardingDbContext> : ITableRouteRuleEngine<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
private readonly IVirtualTableManager _virtualTableManager;
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
public TableRouteRuleEngines(IVirtualTableManager virtualTableManager)
public TableRouteRuleEngine(IVirtualTableManager<TShardingDbContext> virtualTableManager)
{
_virtualTableManager = virtualTableManager;
}
public IEnumerable<TableRouteResult> Route<T, TShardingDbContext>(TableRouteRuleContext<T> tableRouteRuleContext) where TShardingDbContext : DbContext, IShardingDbContext
{
return Route(typeof(TShardingDbContext), tableRouteRuleContext);
////先添加手动路由到当前上下文,之后将不再手动路由里面的自动路由添加到当前上下文
//foreach (var kv in tableRouteRuleContext.ManualTails)
//{
// var virtualTable = kv.Key;
// var addTails = kv.Value;
// var physicTables = virtualTable.GetAllPhysicTables().Where(o=>addTails.Contains(o.Tail));
// if (!routeMaps.ContainsKey(virtualTable))
// {
// routeMaps.Add(virtualTable,physicTables.ToHashSet());
// }
// else
// {
// foreach (var physicTable in physicTables)
// {
// routeMaps[virtualTable].Add(physicTable);
// }
// }
//}
//foreach (var kv in tableRouteRuleContext.ManualPredicate)
//{
// var virtualTable = kv.Key;
// var predicate = kv.Value;
// var physicTables = virtualTable.RouteTo(new TableRouteConfig(null, null, null, predicate));
// if (!routeMaps.ContainsKey(virtualTable))
// {
// routeMaps.Add(virtualTable, physicTables.ToHashSet());
// }
// else
// {
// foreach (var physicTable in physicTables)
// {
// routeMaps[virtualTable].Add(physicTable);
// }
// }
//}
//if (tableRouteRuleContext.AutoParseRoute)
//{
// var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
// foreach (var shardingEntity in shardingEntities)
// {
// var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntity);
// var physicTables = virtualTable.RouteTo(new TableRouteConfig(tableRouteRuleContext.Queryable));
// if (!routeMaps.ContainsKey(virtualTable))
// {
// routeMaps.Add(virtualTable, physicTables.ToHashSet());
// }
// else
// {
// foreach (var physicTable in physicTables)
// {
// routeMaps[virtualTable].Add(physicTable);
// }
// }
// }
//}
}
public IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, TableRouteRuleContext<T> tableRouteRuleContext)
public IEnumerable<TableRouteResult> Route<T>(TableRouteRuleContext<T> tableRouteRuleContext)
{
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
var queryEntities = tableRouteRuleContext.Queryable.ParseQueryableRoute();
@ -101,7 +39,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
foreach (var shardingEntity in shardingEntities)
{
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntity);
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntity);
var physicTables = virtualTable.RouteTo(new ShardingTableRouteConfig(tableRouteRuleContext.Queryable));
if (!routeMaps.ContainsKey(virtualTable))

View File

@ -17,15 +17,13 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
/// <summary>
/// 表路由规则引擎工厂
/// </summary>
public class TableRouteRuleEngineFactory : ITableRouteRuleEngineFactory
public class TableRouteRuleEngineFactory<TShardingDbContext> : ITableRouteRuleEngineFactory<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly ITableRouteRuleEngine _tableRouteRuleEngine;
private readonly IVirtualTableManager _virtualTableManager;
private readonly ITableRouteRuleEngine<TShardingDbContext> _tableRouteRuleEngine;
public TableRouteRuleEngineFactory(ITableRouteRuleEngine tableRouteRuleEngine, IVirtualTableManager virtualTableManager)
public TableRouteRuleEngineFactory(ITableRouteRuleEngine<TShardingDbContext> tableRouteRuleEngine)
{
_tableRouteRuleEngine = tableRouteRuleEngine;
_virtualTableManager = virtualTableManager;
}
/// <summary>
/// 创建表路由上下文
@ -36,18 +34,18 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
/// <returns></returns>
public TableRouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable)
{
return new TableRouteRuleContext<T>(queryable, _virtualTableManager);
return new TableRouteRuleContext<T>(queryable);
}
public IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, IQueryable<T> queryable)
public IEnumerable<TableRouteResult> Route<T>(IQueryable<T> queryable)
{
var ruleContext = CreateContext<T>(queryable);
return _tableRouteRuleEngine.Route(shardingDbContextType,ruleContext);
return _tableRouteRuleEngine.Route(ruleContext);
}
public IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, TableRouteRuleContext<T> ruleContext)
public IEnumerable<TableRouteResult> Route<T>(TableRouteRuleContext<T> ruleContext)
{
return _tableRouteRuleEngine.Route(shardingDbContextType,ruleContext);
return _tableRouteRuleEngine.Route(ruleContext);
}
}
}

View File

@ -13,13 +13,17 @@ using ShardingCore.Sharding.Abstractions;
using ShardingCore.TableCreator;
using System;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection.Extensions;
using ShardingCore.Core.QueryRouteManagers;
using ShardingCore.Core.QueryRouteManagers.Abstractions;
using ShardingCore.Core.ShardingPage;
using ShardingCore.Core.ShardingPage.Abstractions;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.DIExtensions;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
using ShardingCore.Sharding.ShardingQueryExecutors;
@ -34,25 +38,15 @@ namespace ShardingCore
*/
public static class DIExtension
{
public static IServiceCollection AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
public static ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
Action<DbContextOptionsBuilder> optionsAction = null,
Action<ShardingConfigOption<TShardingDbContext,TActualDbContext>> configure=null,
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
where TActualDbContext : DbContext, IShardingTableDbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
if (configure == null)
throw new ArgumentNullException($"AddShardingDbContext params is null :{nameof(configure)}");
ShardingCoreHelper.CheckContextConstructors<TActualDbContext>();
var shardingConfigOptions = new ShardingConfigOption<TShardingDbContext,TActualDbContext>();
configure?.Invoke(shardingConfigOptions);
services.AddSingleton<IShardingConfigOption, ShardingConfigOption<TShardingDbContext, TActualDbContext>>(sp=> shardingConfigOptions);
services.AddShardingBaseOptions(shardingConfigOptions);
ShardingCoreHelper.CheckContextConstructors<TActualDbContext>();
Action<DbContextOptionsBuilder> shardingOptionAction = option =>
{
optionsAction?.Invoke(option);
@ -60,120 +54,173 @@ namespace ShardingCore
};
services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
services.AddInternalShardingCore();
return services;
return new ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext>(services);
}
public static IServiceCollection AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
Action<IServiceProvider,DbContextOptionsBuilder> optionsAction = null,
Action<ShardingConfigOption<TShardingDbContext,TActualDbContext>> configure=null,
public static ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
Action<IServiceProvider, DbContextOptionsBuilder> optionsAction = null,
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
where TActualDbContext : DbContext, IShardingTableDbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
if (configure == null)
throw new ArgumentNullException($"AddShardingDbContext params is null :{nameof(configure)}");
ShardingCoreHelper.CheckContextConstructors<TActualDbContext>();
var shardingConfigOptions = new ShardingConfigOption<TShardingDbContext,TActualDbContext>();
configure?.Invoke(shardingConfigOptions);
services.AddSingleton<IShardingConfigOption, ShardingConfigOption<TShardingDbContext, TActualDbContext>>(sp=> shardingConfigOptions);
services.AddShardingBaseOptions(shardingConfigOptions);
Action<IServiceProvider, DbContextOptionsBuilder> shardingOptionAction = (sp, option) =>
{
optionsAction?.Invoke(sp,option);
optionsAction?.Invoke(sp, option);
option.UseSharding();
};
services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
services.AddInternalShardingCore();
return services;
return new ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext>(services);
}
internal static void AddShardingBaseOptions<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
ShardingConfigOption<TShardingDbContext, TActualDbContext> shardingConfigOptions)
where TActualDbContext : DbContext, IShardingTableDbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
//public static IServiceCollection AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
// Action<DbContextOptionsBuilder> optionsAction = null,
// Action<ShardingConfigOption<TShardingDbContext>> configure=null,
// ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
// ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
// where TActualDbContext : DbContext, IShardingTableDbContext
// where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
//{
// if (configure == null)
// throw new ArgumentNullException($"AddShardingDbContext params is null :{nameof(configure)}");
//添加创建TActualDbContext 的DbContextOptionsBuilder创建者
var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(shardingConfigOptions.SameConnectionConfigure, shardingConfigOptions.DefaultQueryConfigure);
services.AddSingleton<IShardingDbContextOptionsBuilderConfig, ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp => config);
// ShardingCoreHelper.CheckContextConstructors<TActualDbContext>();
// var shardingConfigOptions = new ShardingConfigOption<TShardingDbContext>();
// configure?.Invoke(shardingConfigOptions);
// services.AddSingleton<IShardingConfigOption, ShardingConfigOption<TShardingDbContext>>(sp=> shardingConfigOptions);
//添加创建TActualDbContext创建者
services.AddSingleton<IShardingDbContextCreatorConfig, DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>>(sp => new DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>(typeof(TActualDbContext)));
// services.AddShardingBaseOptions<TShardingDbContext, TActualDbContext>(shardingConfigOptions);
if (!shardingConfigOptions.UseReadWrite)
{
services.AddTransient<IConnectionStringManager, DefaultConnectionStringManager<TShardingDbContext>>();
}
else
{
services.AddTransient<IConnectionStringManager, ReadWriteConnectionStringManager<TShardingDbContext>>();
// Action<DbContextOptionsBuilder> shardingOptionAction = option =>
// {
// optionsAction?.Invoke(option);
// option.UseSharding();
services.AddSingleton<IReadWriteOptions, ReadWriteOptions<TShardingDbContext>>(sp=>new ReadWriteOptions<TShardingDbContext>(shardingConfigOptions.ReadWriteDefaultPriority, shardingConfigOptions.ReadWriteDefaultEnable, shardingConfigOptions.ReadConnStringGetStrategy));
if (shardingConfigOptions.ReadStrategyEnum == ReadStrategyEnum.Loop)
{
services
.AddSingleton<IShardingConnectionStringResolver,
LoopShardingConnectionStringResolver<TShardingDbContext>>(sp =>
new LoopShardingConnectionStringResolver<TShardingDbContext>(
shardingConfigOptions.ReadConnStringConfigure(sp)));
}else if (shardingConfigOptions.ReadStrategyEnum == ReadStrategyEnum.Random)
{
services
.AddSingleton<IShardingConnectionStringResolver,
RandomShardingConnectionStringResolver<TShardingDbContext>>(sp =>
new RandomShardingConnectionStringResolver<TShardingDbContext>(
shardingConfigOptions.ReadConnStringConfigure(sp)));
}
// };
// services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
// services.AddInternalShardingCore();
services.AddSingleton<IShardingReadWriteManager, ShardingReadWriteManager>();
services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
}
}
// return services;
//}
//public static IServiceCollection AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
// Action<IServiceProvider,DbContextOptionsBuilder> optionsAction = null,
// Action<ShardingConfigOption<TShardingDbContext>> configure=null,
// ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
// ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
// where TActualDbContext : DbContext, IShardingTableDbContext
// where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
//{
// if (configure == null)
// throw new ArgumentNullException($"AddShardingDbContext params is null :{nameof(configure)}");
// ShardingCoreHelper.CheckContextConstructors<TActualDbContext>();
// var shardingConfigOptions = new ShardingConfigOption<TShardingDbContext>();
// configure?.Invoke(shardingConfigOptions);
// services.AddSingleton<IShardingConfigOption, ShardingConfigOption<TShardingDbContext>>(sp=> shardingConfigOptions);
// services.AddShardingBaseOptions<TShardingDbContext,TActualDbContext>(shardingConfigOptions);
// Action<IServiceProvider, DbContextOptionsBuilder> shardingOptionAction = (sp, option) =>
// {
// optionsAction?.Invoke(sp,option);
// option.UseSharding();
// };
// services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
// services.AddInternalShardingCore();
// return services;
//}
//internal static void AddShardingBaseOptions<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
// ShardingConfigOption<TShardingDbContext> shardingConfigOptions)
// where TActualDbContext : DbContext, IShardingTableDbContext
// where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
//{
// //添加创建TActualDbContext 的DbContextOptionsBuilder创建者
// var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(shardingConfigOptions.SameConnectionConfigure, shardingConfigOptions.DefaultQueryConfigure);
// services.AddSingleton<IShardingDbContextOptionsBuilderConfig<TShardingDbContext>, ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp => config);
// //添加创建TActualDbContext创建者
// services.AddSingleton<IShardingDbContextCreatorConfig, DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>>(sp => new DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>(typeof(TActualDbContext)));
// if (!shardingConfigOptions.UseReadWrite)
// {
// services.AddTransient<IConnectionStringManager, DefaultConnectionStringManager<TShardingDbContext>>();
// }
// else
// {
// services.AddTransient<IConnectionStringManager, ReadWriteConnectionStringManager<TShardingDbContext>>();
// services.AddSingleton<IReadWriteOptions, ReadWriteOptions<TShardingDbContext>>(sp=>new ReadWriteOptions<TShardingDbContext>(shardingConfigOptions.ReadWriteDefaultPriority, shardingConfigOptions.ReadWriteDefaultEnable, shardingConfigOptions.ReadConnStringGetStrategy));
// //if (shardingConfigOptions.ReadStrategyEnum == ReadStrategyEnum.Loop)
// //{
// // services
// // .AddSingleton<IShardingConnectionStringResolver,
// // LoopShardingConnectionStringResolver<TShardingDbContext>>(sp =>
// // new LoopShardingConnectionStringResolver<TShardingDbContext>(
// // shardingConfigOptions.ReadConnStringConfigure(sp)));
// //}else if (shardingConfigOptions.ReadStrategyEnum == ReadStrategyEnum.Random)
// //{
// // services
// // .AddSingleton<IShardingConnectionStringResolver,
// // RandomShardingConnectionStringResolver<TShardingDbContext>>(sp =>
// // new RandomShardingConnectionStringResolver<TShardingDbContext>(
// // shardingConfigOptions.ReadConnStringConfigure(sp)));
// //}
// services.TryAddSingleton<IShardingReadWriteManager, ShardingReadWriteManager>();
// services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
// }
//}
internal static IServiceCollection AddInternalShardingCore(this IServiceCollection services)
{
services.AddSingleton<IStreamMergeContextFactory, StreamMergeContextFactory>();
services.TryAddSingleton(typeof(IStreamMergeContextFactory<>),typeof(StreamMergeContextFactory<>));
services.TryAddSingleton(typeof(IShardingTableCreator<>),typeof(ShardingTableCreator<>));
//虚拟数据源管理
services.TryAddSingleton(typeof(IVirtualDataSource<>), typeof(VirtualDataSource<>));
services.TryAddSingleton(typeof(IDataSourceRouteRuleEngine<>), typeof(DataSourceRouteRuleEngine<>));
services.TryAddSingleton(typeof(IDataSourceRouteRuleEngineFactory<>), typeof(DataSourceRouteRuleEngineFactory<>));
//虚拟表管理
services.TryAddSingleton(typeof(IVirtualTableManager<>),typeof(VirtualTableManager<>));
//分表dbcontext创建
services.TryAddSingleton(typeof(IShardingDbContextFactory<>), typeof(ShardingDbContextFactory<>));
services.AddSingleton<IShardingDbContextFactory, ShardingDbContextFactory>();
services.AddSingleton<IShardingTableCreator, ShardingTableCreator>();
//分表
services.AddSingleton<IVirtualTableManager, DefaultVirtualTableManager>();
//分表引擎工程
services.AddSingleton<ITableRouteRuleEngineFactory, TableRouteRuleEngineFactory>();
//分表引擎
services.AddSingleton<ITableRouteRuleEngine, TableRouteRuleEngines>();
services.AddSingleton<IRouteTailFactory, RouteTailFactory>();
services.AddSingleton<IShardingQueryExecutor, DefaultShardingQueryExecutor>();
services.TryAddSingleton(typeof(ITableRouteRuleEngine<>),typeof(TableRouteRuleEngine<>));
//分表引擎工程
services.TryAddSingleton(typeof(ITableRouteRuleEngineFactory<>),typeof(TableRouteRuleEngineFactory<>));
services.TryAddSingleton<IRouteTailFactory, RouteTailFactory>();
services.TryAddSingleton<IShardingQueryExecutor, DefaultShardingQueryExecutor>();
//route manage
services.AddSingleton<IShardingRouteManager, ShardingRouteManager>();
services.AddSingleton<IShardingRouteAccessor, ShardingRouteAccessor>();
services.TryAddSingleton<IShardingRouteManager, ShardingRouteManager>();
services.TryAddSingleton<IShardingRouteAccessor, ShardingRouteAccessor>();
//sharding page
services.AddSingleton<IShardingPageManager, ShardingPageManager>();
services.AddSingleton<IShardingPageAccessor, ShardingPageAccessor>();
services.AddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
services.TryAddSingleton<IShardingPageManager, ShardingPageManager>();
services.TryAddSingleton<IShardingPageAccessor, ShardingPageAccessor>();
services.TryAddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
return services;
}
internal static DbContextOptionsBuilder UseSharding(this DbContextOptionsBuilder optionsBuilder)
{
return optionsBuilder.ReplaceService<IDbSetSource, ShardingDbSetSource>()
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>()
.ReplaceService<IRelationalTransactionFactory, ShardingRelationalTransactionFactory>();
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>();
//.ReplaceService<IRelationalTransactionFactory, ShardingRelationalTransactionFactory>();
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 20:49:03
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
public IServiceCollection Services { get; }
public ShardingConfigOption<TShardingDbContext> ShardingConfigOption { get; }
public ShardingCoreConfigBuilder(IServiceCollection services)
{
Services = services;
ShardingConfigOption = new ShardingConfigOption<TShardingDbContext>();
}
public ShardingQueryBuilder<TShardingDbContext, TActualDbContext> Begin(bool ensureCreatedWithOutShardingTable, bool? createShardingTableOnStart = null,bool? ignoreCreateTableError = null)
{
ShardingConfigOption.EnsureCreatedWithOutShardingTable = ensureCreatedWithOutShardingTable;
ShardingConfigOption.CreateShardingTableOnStart = createShardingTableOnStart;
ShardingConfigOption.IgnoreCreateTableError = ignoreCreateTableError;
return new ShardingQueryBuilder<TShardingDbContext, TActualDbContext>(this);
}
//public ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> AddDefaultDataSource(string dataSourceName, string connectionString)
//{
// if (!string.IsNullOrWhiteSpace(defaultDataSourceName) || !string.IsNullOrWhiteSpace(defaultConnectionString))
// throw new InvalidOperationException($"{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 InvalidOperationException($"{nameof(AddDataSource)}-{dataSourceName} repeat");
// _dataSources.Add(dataSourceName, connectionString);
// return this;
//}
}
}

View File

@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 22:36:20
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingCoreConfigEndBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingCoreConfigEndBuilder(
ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public IServiceCollection End()
{
var services = _shardingCoreConfigBuilder.Services;
services.AddSingleton<IShardingConfigOption, ShardingConfigOption<TShardingDbContext>>(sp =>
_shardingCoreConfigBuilder.ShardingConfigOption);
//添加创建TActualDbContext 的DbContextOptionsBuilder创建者
var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(
_shardingCoreConfigBuilder.ShardingConfigOption.SameConnectionConfigure,
_shardingCoreConfigBuilder.ShardingConfigOption.DefaultQueryConfigure);
services
.AddSingleton<IShardingDbContextOptionsBuilderConfig<TShardingDbContext>,
ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp => config);
//添加创建TActualDbContext创建者
services
.AddSingleton<IShardingDbContextCreatorConfig,
DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>>(sp =>
new DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>(
typeof(TActualDbContext)));
if (!_shardingCoreConfigBuilder.ShardingConfigOption.UseReadWrite)
{
services.AddTransient<IConnectionStringManager<TShardingDbContext>, DefaultConnectionStringManager<TShardingDbContext>>();
}
else
{
services.AddTransient<IConnectionStringManager<TShardingDbContext>, ReadWriteConnectionStringManager<TShardingDbContext>>();
services.AddSingleton<IReadWriteOptions, ReadWriteOptions<TShardingDbContext>>(sp =>
new ReadWriteOptions<TShardingDbContext>(
_shardingCoreConfigBuilder.ShardingConfigOption.ReadWriteDefaultPriority,
_shardingCoreConfigBuilder.ShardingConfigOption.ReadWriteDefaultEnable,
_shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringGetStrategy));
if (_shardingCoreConfigBuilder.ShardingConfigOption.ReadStrategyEnum == ReadStrategyEnum.Loop)
{
services
.AddSingleton<IShardingConnectionStringResolver,
LoopShardingConnectionStringResolver<TShardingDbContext>>(sp =>
{
var readConnString = _shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringConfigure(sp);
var readWriteLoopConnectors = readConnString.Select(o => new ReadWriteLoopConnector(o.Key, o.Value));
return new LoopShardingConnectionStringResolver<TShardingDbContext>(
readWriteLoopConnectors);
});
}
else if (_shardingCoreConfigBuilder.ShardingConfigOption.ReadStrategyEnum == ReadStrategyEnum.Random)
{
services
.AddSingleton<IShardingConnectionStringResolver,
RandomShardingConnectionStringResolver<TShardingDbContext>>(sp =>
{
var readConnString = _shardingCoreConfigBuilder.ShardingConfigOption.ReadConnStringConfigure(sp);
var readWriteRandomConnectors = readConnString.Select(o => new ReadWriteRandomConnector(o.Key, o.Value));
return new RandomShardingConnectionStringResolver<TShardingDbContext>(
readWriteRandomConnectors);
});
}
services.TryAddSingleton<IShardingReadWriteManager, ShardingReadWriteManager>();
services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
//foreach (var dataSourceKv in dataSources)
//{
// if (dataSourceKv.Key == _shardingCoreConfigBuilder.DefaultDataSourceName)
// throw new InvalidOperationException($"{nameof(AddShardingDataBase)} include default data source name:{_shardingCoreConfigBuilder.DefaultDataSourceName}");
// _shardingCoreConfigBuilder.AddShardingDataSource.Add(dataSourceKv.Key, dataSourceKv.Value);
//}
}
services.AddInternalShardingCore();
return services;
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 21:37:11
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingDataBaseOrTableBuilder<TShardingDbContext, TActualDbContext>: ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingDataBaseOrTableBuilder(ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder):base(shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public ShardingTableBuilder<TShardingDbContext, TActualDbContext> AddShardingDataBase(Func<IServiceProvider, IDictionary<string, string>> dataSourcesConfigure, Action<ShardingDatabaseOptions> shardingDatabaseConfigure)
{
_shardingCoreConfigBuilder.ShardingConfigOption.AddShardingDataSource(dataSourcesConfigure);
var shardingDatabaseOptions = new ShardingDatabaseOptions();
shardingDatabaseConfigure.Invoke(shardingDatabaseOptions);
var shardingDatabaseRoutes = shardingDatabaseOptions.GetShardingDatabaseRoutes();
foreach (var shardingDatabaseRoute in shardingDatabaseRoutes)
{
_shardingCoreConfigBuilder.ShardingConfigOption.AddShardingDataSourceRoute(shardingDatabaseRoute);
}
return new ShardingTableBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
public ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext> AddShardingTable(Action<ShardingTableOptions> shardingTableConfigure)
{
var shardingTableOptions = new ShardingTableOptions();
shardingTableConfigure.Invoke(shardingTableOptions);
var shardingTableRoutes = shardingTableOptions.GetShardingTableRoutes();
foreach (var shardingTableRoute in shardingTableRoutes)
{
_shardingCoreConfigBuilder.ShardingConfigOption.AddShardingTableRoute(shardingTableRoute);
}
return new ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 22:21:45
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingDatabaseOptions
{
private readonly ICollection<Type> _virtualDataSourceRoutes = new LinkedList<Type>();
/// <summary>
/// 添加分表路由
/// </summary>
/// <typeparam name="TRoute"></typeparam>
public void AddShardingDatabaseRoute<TRoute>() where TRoute : IVirtualDataSourceRoute
{
var routeType = typeof(TRoute);
_virtualDataSourceRoutes.Add(routeType);
}
public ICollection<Type> GetShardingDatabaseRoutes()
{
return _virtualDataSourceRoutes;
}
}
public class ShardingTableOptions
{
private readonly ICollection<Type> _virtualTableRoutes = new LinkedList<Type>();
/// <summary>
/// 添加分表路由
/// </summary>
/// <typeparam name="TRoute"></typeparam>
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
{
var routeType = typeof(TRoute);
_virtualTableRoutes.Add(routeType);
}
public ICollection<Type> GetShardingTableRoutes()
{
return _virtualTableRoutes;
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 21:33:21
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingDefaultDataSourceBuilder<TShardingDbContext, TActualDbContext>: ShardingCoreConfigEndBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingDefaultDataSourceBuilder(ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder):base(shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public ShardingDataBaseOrTableBuilder<TShardingDbContext, TActualDbContext> AddDefaultDataSource(string dataSourceName, string connectionString)
{
if (!string.IsNullOrWhiteSpace(_shardingCoreConfigBuilder.ShardingConfigOption.DefaultDataSourceName) || !string.IsNullOrWhiteSpace(_shardingCoreConfigBuilder.ShardingConfigOption.DefaultConnectionString))
throw new InvalidOperationException($"{nameof(AddDefaultDataSource)}-{dataSourceName}");
_shardingCoreConfigBuilder.ShardingConfigOption.DefaultDataSourceName = dataSourceName;
_shardingCoreConfigBuilder.ShardingConfigOption.DefaultConnectionString = connectionString;
return new ShardingDataBaseOrTableBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 21:11:48
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingQueryBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingQueryBuilder(ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public ShardingTransactionBuilder<TShardingDbContext, TActualDbContext> AddShardingQuery(Action<string, DbContextOptionsBuilder> queryConfigure)
{
_shardingCoreConfigBuilder.ShardingConfigOption.UseShardingQuery(queryConfigure);
return new ShardingTransactionBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ReadWriteConfigurations;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 22:44:54
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext> : ShardingCoreConfigEndBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingReadWriteSeparationBuilder(ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder) : base(shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public ShardingCoreConfigEndBuilder<TShardingDbContext, TActualDbContext> AddReadWriteSeparation(
Func<IServiceProvider, IDictionary<string, ISet<string>>> readWriteSeparationConfigure,
ReadStrategyEnum readStrategyEnum,
bool defaultEnable = false,
int defaultPriority = 10,
ReadConnStringGetStrategyEnum readConnStringGetStrategy = ReadConnStringGetStrategyEnum.LatestFirstTime)
{
_shardingCoreConfigBuilder.ShardingConfigOption.UseReadWriteConfiguration(readWriteSeparationConfigure,readStrategyEnum, defaultEnable,defaultPriority);
return new ShardingCoreConfigEndBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 22:56:44
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingTableBuilder<TShardingDbContext, TActualDbContext> : ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingTableBuilder(ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder) : base(shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext> AddShardingTable(Action<ShardingTableOptions> shardingTableConfigure)
{
var shardingTableOptions = new ShardingTableOptions();
shardingTableConfigure.Invoke(shardingTableOptions);
var shardingTableRoutes = shardingTableOptions.GetShardingTableRoutes();
foreach (var shardingTableRoute in shardingTableRoutes)
{
_shardingCoreConfigBuilder.ShardingConfigOption.AddShardingTableRoute(shardingTableRoute);
}
return new ShardingReadWriteSeparationBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.DIExtensions
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/19 21:13:43
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingTransactionBuilder<TShardingDbContext, TActualDbContext>
where TActualDbContext : DbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
{
private readonly ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> _shardingCoreConfigBuilder;
public ShardingTransactionBuilder(ShardingCoreConfigBuilder<TShardingDbContext, TActualDbContext> shardingCoreConfigBuilder)
{
_shardingCoreConfigBuilder = shardingCoreConfigBuilder;
}
public ShardingDefaultDataSourceBuilder<TShardingDbContext, TActualDbContext> AddShardingTransaction(Action<DbConnection, DbContextOptionsBuilder> transactionConfigure)
{
_shardingCoreConfigBuilder.ShardingConfigOption.UseShardingTransaction(transactionConfigure);
return new ShardingDefaultDataSourceBuilder<TShardingDbContext, TActualDbContext>(_shardingCoreConfigBuilder);
}
}
}

View File

@ -13,11 +13,8 @@ namespace ShardingCore.DbContexts
* @Date: Thursday, 24 December 2020 08:22:23
* @Email: 326308290@qq.com
*/
public interface IShardingDbContextFactory
public interface IShardingDbContextFactory<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
DbContext Create(ShardingDbContextOptions shardingDbContextOptions);
}
public interface IShardingDbContextFactory<TShardingDbContext>: IShardingDbContextFactory where TShardingDbContext:DbContext,IShardingDbContext
{
}
}

View File

@ -15,28 +15,22 @@ namespace ShardingCore.DbContexts
* @Date: Thursday, 24 December 2020 08:22:48
* @Email: 326308290@qq.com
*/
public class ShardingDbContextFactory:IShardingDbContextFactory
public class ShardingDbContextFactory<TShardingDbContext> : IShardingDbContextFactory<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly IEnumerable<IShardingDbContextCreatorConfig> _shardingDbContextCreatorConfigs;
private readonly IShardingDbContextCreatorConfig _shardingDbContextCreatorConfig;
public ShardingDbContextFactory(IEnumerable<IShardingDbContextCreatorConfig> shardingDbContextCreatorConfigs)
{
_shardingDbContextCreatorConfigs = shardingDbContextCreatorConfigs;
_shardingDbContextCreatorConfig = shardingDbContextCreatorConfigs
.FirstOrDefault(o => o.ShardingDbContextType == typeof(TShardingDbContext))
??throw new ShardingCoreException(
$"{typeof(TShardingDbContext).FullName} cant found DefaultShardingDbContextCreatorConfig<{typeof(TShardingDbContext).Name}> should use {nameof(DIExtension.AddShardingDbContext)}");
}
public DbContext Create(Type shardingDbContextType, ShardingDbContextOptions shardingDbContextOptions)
public DbContext Create(ShardingDbContextOptions shardingDbContextOptions)
{
if (!shardingDbContextType.IsShardingDbContext())
throw new ShardingCoreException(
$"{shardingDbContextType.FullName} must impl {nameof(IShardingDbContext)}");
var shardingDbContextCreatorConfig = _shardingDbContextCreatorConfigs.FirstOrDefault(o=>o.ShardingDbContextType==shardingDbContextType);
if (shardingDbContextCreatorConfig == null)
{
throw new ShardingCoreException(
$"{shardingDbContextType.FullName} cant found DefaultShardingDbContextCreatorConfig<{shardingDbContextType.Name}> should use {nameof(DIExtension.AddShardingDbContext)}");
}
var routeTail=shardingDbContextOptions.RouteTail;
var dbContext = shardingDbContextCreatorConfig.Creator(shardingDbContextOptions);
var dbContext = _shardingDbContextCreatorConfig.Creator(shardingDbContextOptions);
if (dbContext is IShardingTableDbContext shardingTableDbContext)
{
shardingTableDbContext.RouteTail = routeTail;
@ -44,11 +38,5 @@ namespace ShardingCore.DbContexts
var dbContextModel = dbContext.Model;
return dbContext;
}
public DbContext Create<TShardingDbContext>(ShardingDbContextOptions shardingDbContextOptions) where TShardingDbContext : DbContext, IShardingDbContext
{
return Create(typeof(TShardingDbContext), shardingDbContextOptions);
}
}
}

View File

@ -15,7 +15,7 @@ namespace ShardingCore
*/
public class DefaultShardingDbContextCreatorConfig<TShardingDbContext,TActualDbContext> : IShardingDbContextCreatorConfig
where TShardingDbContext : DbContext, IShardingDbContext
where TActualDbContext : DbContext, IShardingTableDbContext
where TActualDbContext : DbContext
{
private readonly Func<ShardingDbContextOptions, DbContext> _creator;
public DefaultShardingDbContextCreatorConfig(Type actualDbContextType)

View File

@ -1,65 +1,65 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ShardingTransactions;
//using System;
//using System.Collections.Generic;
//using System.Data.Common;
//using System.Text;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.EntityFrameworkCore.Diagnostics;
//using Microsoft.EntityFrameworkCore.Infrastructure;
//using Microsoft.EntityFrameworkCore.Storage;
//using ShardingCore.Sharding.Abstractions;
//using ShardingCore.Sharding.ShardingTransactions;
namespace ShardingCore.EFCores
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/5 20:37:36
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRelationalTransaction : RelationalTransaction
{
private readonly IShardingTransaction _shardingDbContext;
public ShardingRelationalTransaction(IRelationalConnection connection, DbTransaction transaction, Guid transactionId, IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned) : base(connection, transaction, transactionId, logger, transactionOwned)
{
_shardingDbContext = (IShardingDbContext)null;
_shardingDbContext.UseShardingTransaction(transaction);
}
//namespace ShardingCore.EFCores
//{
// /*
// * @Author: xjm
// * @Description:
// * @Date: 2021/9/5 20:37:36
// * @Ver: 1.0
// * @Email: 326308290@qq.com
// */
// public class ShardingRelationalTransaction : RelationalTransaction
// {
// private readonly IShardingTransaction _shardingDbContext;
// public ShardingRelationalTransaction(IRelationalConnection connection, DbTransaction transaction, Guid transactionId, IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned) : base(connection, transaction, transactionId, logger, transactionOwned)
// {
// _shardingDbContext = (IShardingDbContext)null;
// _shardingDbContext.UseShardingTransaction(transaction);
// }
protected override void ClearTransaction()
{
base.ClearTransaction();
_shardingDbContext.UseShardingTransaction(null);
}
// protected override void ClearTransaction()
// {
// base.ClearTransaction();
// _shardingDbContext.UseShardingTransaction(null);
// }
protected override async Task ClearTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
{
await base.ClearTransactionAsync(cancellationToken);
_shardingDbContext.UseShardingTransaction(null);
// protected override async Task ClearTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// await base.ClearTransactionAsync(cancellationToken);
// _shardingDbContext.UseShardingTransaction(null);
}
// }
public override void Commit()
{
base.Commit();
}
// public override void Commit()
// {
// base.Commit();
// }
public override Task CommitAsync(CancellationToken cancellationToken = new CancellationToken())
{
return base.CommitAsync(cancellationToken);
}
// public override Task CommitAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// return base.CommitAsync(cancellationToken);
// }
public override void Rollback()
{
base.Rollback();
}
// public override void Rollback()
// {
// base.Rollback();
// }
public override Task RollbackAsync(CancellationToken cancellationToken = new CancellationToken())
{
return base.RollbackAsync(cancellationToken);
}
}
}
// public override Task RollbackAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// return base.RollbackAsync(cancellationToken);
// }
// }
//}

View File

@ -40,8 +40,8 @@ namespace ShardingCore.EFCores
{
var singleQueryRouteTail = (ISingleQueryRouteTail) shardingTableDbContext.RouteTail;
var tail = singleQueryRouteTail.GetTail();
var virtualTableManager = ShardingContainer.Services.GetService<IVirtualTableManager>();
var typeMap = virtualTableManager.GetAllVirtualTables(_shardingDbContextType).Where(o => o.GetTaleAllTails().Contains(tail)).Select(o => o.EntityType).ToHashSet();
var virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
var typeMap = virtualTableManager.GetAllVirtualTables().Where(o => o.GetTaleAllTails().Contains(tail)).Select(o => o.EntityType).ToHashSet();
//设置分表
var mutableEntityTypes = modelBuilder.Model.GetEntityTypes().Where(o => o.ClrType.IsShardingTable() && typeMap.Contains(o.ClrType));

View File

@ -1,205 +1,205 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ShardingTransactions;
//using System;
//using System.Collections.Generic;
//using System.Data;
//using System.Data.Common;
//using System.Text;
//using System.Threading;
//using System.Threading.Tasks;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.EntityFrameworkCore.Internal;
//using Microsoft.EntityFrameworkCore.Query.Internal;
//using Microsoft.EntityFrameworkCore.Storage;
//using Microsoft.EntityFrameworkCore.Storage.Internal;
//using Microsoft.Extensions.DependencyInjection;
//using ShardingCore.Extensions;
//using ShardingCore.Sharding.Abstractions;
//using ShardingCore.Sharding.ShardingTransactions;
namespace ShardingCore.EFCores
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/5 15:41:20
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRelationalConnection : IRelationalConnection
{
private readonly IRelationalConnection _relationalConnection;
//namespace ShardingCore.EFCores
//{
// /*
// * @Author: xjm
// * @Description:
// * @Date: 2021/9/5 15:41:20
// * @Ver: 1.0
// * @Email: 326308290@qq.com
// */
// public class ShardingRelationalConnection : IRelationalConnection
// {
// private readonly IRelationalConnection _relationalConnection;
private readonly ISupportShardingTransaction _supportShardingTransaction;
public ShardingRelationalConnection(IRelationalConnection _relationalConnection, DbTransaction transaction)
{
this._relationalConnection = _relationalConnection;
if (Context is ISupportShardingTransaction supportShardingTransaction)
{
_supportShardingTransaction = supportShardingTransaction;
}
}
// private readonly ISupportShardingTransaction _supportShardingTransaction;
// public ShardingRelationalConnection(IRelationalConnection _relationalConnection, DbTransaction transaction)
// {
// this._relationalConnection = _relationalConnection;
// if (Context is ISupportShardingTransaction supportShardingTransaction)
// {
// _supportShardingTransaction = supportShardingTransaction;
// }
// }
public void ResetState()
{
_relationalConnection.ResetState();
}
// public void ResetState()
// {
// _relationalConnection.ResetState();
// }
public Task ResetStateAsync(CancellationToken cancellationToken = new CancellationToken())
{
return _relationalConnection.ResetStateAsync(cancellationToken);
}
// public Task ResetStateAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// return _relationalConnection.ResetStateAsync(cancellationToken);
// }
public IDbContextTransaction BeginTransaction()
{
var dbContextTransaction = _relationalConnection.BeginTransaction();
_supportShardingTransaction?.BeginTransaction();
return dbContextTransaction;
}
// public IDbContextTransaction BeginTransaction()
// {
// var dbContextTransaction = _relationalConnection.BeginTransaction();
// _supportShardingTransaction?.BeginTransaction();
// return dbContextTransaction;
// }
public async Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
{
var dbContextTransaction = await _relationalConnection.BeginTransactionAsync(cancellationToken);
_supportShardingTransaction?.BeginTransaction();
return dbContextTransaction;
}
// public async Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// var dbContextTransaction = await _relationalConnection.BeginTransactionAsync(cancellationToken);
// _supportShardingTransaction?.BeginTransaction();
// return dbContextTransaction;
// }
public void CommitTransaction()
{
_relationalConnection.CommitTransaction();
_supportShardingTransaction?.Commit();
}
// public void CommitTransaction()
// {
// _relationalConnection.CommitTransaction();
// _supportShardingTransaction?.Commit();
// }
public void RollbackTransaction()
{
_relationalConnection.RollbackTransaction();
_supportShardingTransaction?.Rollback();
}
#if EFCORE5
public IDbContextTransaction UseTransaction(DbTransaction transaction, Guid transactionId)
{
var dbContextTransaction = _relationalConnection.UseTransaction(transaction, transactionId);
_supportShardingTransaction?.UseTransaction(transaction);
return dbContextTransaction;
}
public async Task<IDbContextTransaction> UseTransactionAsync(DbTransaction transaction, Guid transactionId,
CancellationToken cancellationToken = new CancellationToken())
{
var dbContextTransaction = await _relationalConnection.UseTransactionAsync(transaction, transactionId, cancellationToken);
_supportShardingTransaction?.UseTransaction(transaction);
return dbContextTransaction;
}
// public void RollbackTransaction()
// {
// _relationalConnection.RollbackTransaction();
// _supportShardingTransaction?.Rollback();
// }
//#if EFCORE5
// public IDbContextTransaction UseTransaction(DbTransaction transaction, Guid transactionId)
// {
// var dbContextTransaction = _relationalConnection.UseTransaction(transaction, transactionId);
// _supportShardingTransaction?.UseTransaction(transaction);
// return dbContextTransaction;
// }
// public async Task<IDbContextTransaction> UseTransactionAsync(DbTransaction transaction, Guid transactionId,
// CancellationToken cancellationToken = new CancellationToken())
// {
// var dbContextTransaction = await _relationalConnection.UseTransactionAsync(transaction, transactionId, cancellationToken);
// _supportShardingTransaction?.UseTransaction(transaction);
// return dbContextTransaction;
// }
public async Task CommitTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
{
await _relationalConnection.CommitTransactionAsync(cancellationToken);
// public async Task CommitTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// await _relationalConnection.CommitTransactionAsync(cancellationToken);
if (_supportShardingTransaction != null)
await _supportShardingTransaction.CommitAsync(cancellationToken);
// if (_supportShardingTransaction != null)
// await _supportShardingTransaction.CommitAsync(cancellationToken);
}
public async Task RollbackTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
{
await _relationalConnection.RollbackTransactionAsync(cancellationToken);
if (_supportShardingTransaction != null)
await _supportShardingTransaction.RollbackAsync(cancellationToken);
}
#endif
// }
// public async Task RollbackTransactionAsync(CancellationToken cancellationToken = new CancellationToken())
// {
// await _relationalConnection.RollbackTransactionAsync(cancellationToken);
// if (_supportShardingTransaction != null)
// await _supportShardingTransaction.RollbackAsync(cancellationToken);
// }
//#endif
#if !EFCORE5
public bool IsMultipleActiveResultSetsEnabled => _relationalConnection.IsMultipleActiveResultSetsEnabled;
//#if !EFCORE5
// public bool IsMultipleActiveResultSetsEnabled => _relationalConnection.IsMultipleActiveResultSetsEnabled;
# endif
IDbContextTransaction IRelationalConnection.CurrentTransaction => _relationalConnection.CurrentTransaction;
//# endif
// IDbContextTransaction IRelationalConnection.CurrentTransaction => _relationalConnection.CurrentTransaction;
IDbContextTransaction IDbContextTransactionManager.CurrentTransaction => _relationalConnection.CurrentTransaction;
// IDbContextTransaction IDbContextTransactionManager.CurrentTransaction => _relationalConnection.CurrentTransaction;
public SemaphoreSlim Semaphore => _relationalConnection.Semaphore;
// public SemaphoreSlim Semaphore => _relationalConnection.Semaphore;
public bool Open(bool errorsExpected = false)
{
return _relationalConnection.Open(errorsExpected);
}
// public bool Open(bool errorsExpected = false)
// {
// return _relationalConnection.Open(errorsExpected);
// }
public Task<bool> OpenAsync(CancellationToken cancellationToken, bool errorsExpected = false)
{
return _relationalConnection.OpenAsync(cancellationToken, errorsExpected);
}
// public Task<bool> OpenAsync(CancellationToken cancellationToken, bool errorsExpected = false)
// {
// return _relationalConnection.OpenAsync(cancellationToken, errorsExpected);
// }
public bool Close()
{
return _relationalConnection.Close();
}
// public bool Close()
// {
// return _relationalConnection.Close();
// }
public DbConnection DbConnection => _relationalConnection.DbConnection;
// public DbConnection DbConnection => _relationalConnection.DbConnection;
public DbContext Context =>
_relationalConnection.Context;
public Guid ConnectionId => _relationalConnection.ConnectionId;
// public DbContext Context =>
// _relationalConnection.Context;
// public Guid ConnectionId => _relationalConnection.ConnectionId;
public int? CommandTimeout
{
get
{
return _relationalConnection.CommandTimeout;
}
set
{
_relationalConnection.CommandTimeout = value;
}
}
// public int? CommandTimeout
// {
// get
// {
// return _relationalConnection.CommandTimeout;
// }
// set
// {
// _relationalConnection.CommandTimeout = value;
// }
// }
public IDbContextTransaction BeginTransaction(IsolationLevel isolationLevel)
{
var dbContextTransaction = _relationalConnection.BeginTransaction(isolationLevel);
_supportShardingTransaction?.BeginTransaction(isolationLevel);
return dbContextTransaction;
}
// public IDbContextTransaction BeginTransaction(IsolationLevel isolationLevel)
// {
// var dbContextTransaction = _relationalConnection.BeginTransaction(isolationLevel);
// _supportShardingTransaction?.BeginTransaction(isolationLevel);
// return dbContextTransaction;
// }
public async Task<IDbContextTransaction> BeginTransactionAsync(IsolationLevel isolationLevel,
CancellationToken cancellationToken = new CancellationToken())
{
var dbContextTransaction = await _relationalConnection.BeginTransactionAsync(isolationLevel, cancellationToken);
_supportShardingTransaction?.BeginTransaction(isolationLevel);
return dbContextTransaction;
}
// public async Task<IDbContextTransaction> BeginTransactionAsync(IsolationLevel isolationLevel,
// CancellationToken cancellationToken = new CancellationToken())
// {
// var dbContextTransaction = await _relationalConnection.BeginTransactionAsync(isolationLevel, cancellationToken);
// _supportShardingTransaction?.BeginTransaction(isolationLevel);
// return dbContextTransaction;
// }
public IDbContextTransaction UseTransaction(DbTransaction transaction)
{
var dbContextTransaction = _relationalConnection.UseTransaction(transaction);
_supportShardingTransaction?.UseTransaction(transaction);
return dbContextTransaction;
}
// public IDbContextTransaction UseTransaction(DbTransaction transaction)
// {
// var dbContextTransaction = _relationalConnection.UseTransaction(transaction);
// _supportShardingTransaction?.UseTransaction(transaction);
// return dbContextTransaction;
// }
public void Dispose()
{
_relationalConnection.Dispose();
}
// public void Dispose()
// {
// _relationalConnection.Dispose();
// }
public string ConnectionString => _relationalConnection.ConnectionString;
// public string ConnectionString => _relationalConnection.ConnectionString;
public async Task<IDbContextTransaction> UseTransactionAsync(DbTransaction transaction, CancellationToken cancellationToken = new CancellationToken())
{
var dbContextTransaction = await _relationalConnection.UseTransactionAsync(transaction, cancellationToken);
((IShardingTransaction)Context).UseShardingTransaction(transaction);
return dbContextTransaction;
// public async Task<IDbContextTransaction> UseTransactionAsync(DbTransaction transaction, CancellationToken cancellationToken = new CancellationToken())
// {
// var dbContextTransaction = await _relationalConnection.UseTransactionAsync(transaction, cancellationToken);
// ((IShardingTransaction)Context).UseShardingTransaction(transaction);
// return dbContextTransaction;
}
// }
public Task<bool> CloseAsync()
{
return _relationalConnection.CloseAsync();
}
// public Task<bool> CloseAsync()
// {
// return _relationalConnection.CloseAsync();
// }
public ValueTask DisposeAsync()
{
return _relationalConnection.DisposeAsync();
}
}
}
// public ValueTask DisposeAsync()
// {
// return _relationalConnection.DisposeAsync();
// }
// }
//}

View File

@ -1,33 +1,33 @@
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore.Sharding.Abstractions;
//using System;
//using System.Collections.Generic;
//using System.Data.Common;
//using System.Text;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.EntityFrameworkCore.Diagnostics;
//using Microsoft.EntityFrameworkCore.Infrastructure;
//using Microsoft.EntityFrameworkCore.Storage;
//using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.EFCores
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/5 16:03:04
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingRelationalTransactionFactory: RelationalTransactionFactory
{
private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)
{
_dependencies = dependencies;
}
public override RelationalTransaction Create(IRelationalConnection connection, DbTransaction transaction, Guid transactionId,
IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned)
{
return new RelationalTransaction(new ShardingRelationalConnection(connection, transaction), transaction, transactionId, logger, transactionOwned);
}
}
}
//namespace ShardingCore.EFCores
//{
// /*
// * @Author: xjm
// * @Description:
// * @Date: 2021/9/5 16:03:04
// * @Ver: 1.0
// * @Email: 326308290@qq.com
// */
// public class ShardingRelationalTransactionFactory: RelationalTransactionFactory
// {
// private readonly RelationalTransactionFactoryDependencies _dependencies;
// public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)
// {
// _dependencies = dependencies;
// }
// public override RelationalTransaction Create(IRelationalConnection connection, DbTransaction transaction, Guid transactionId,
// IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned)
// {
// return new RelationalTransaction(new ShardingRelationalConnection(connection, transaction), transaction, transactionId, logger, transactionOwned);
// }
// }
//}

View File

@ -7,12 +7,14 @@ using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using ShardingCore.Core;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Exceptions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Utils;
namespace ShardingCore.Extensions
{
@ -68,26 +70,86 @@ namespace ShardingCore.Extensions
/// <summary>
/// 根据对象集合解析
/// </summary>
/// <typeparam name="TShardingDbContext"></typeparam>
/// <typeparam name="TEntity"></typeparam>
/// <param name="shardingDbContext"></param>
/// <param name="entities"></param>
/// <returns></returns>
public static IDictionary<DbContext, IEnumerable<TEntity>> BulkShardingEnumerable<TEntity>(this IShardingDbContext shardingDbContext,
IEnumerable<TEntity> entities) where TEntity : class
public static IDictionary<DbContext, IEnumerable<TEntity>> BulkShardingEnumerable<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext,
IEnumerable<TEntity> entities) where TShardingDbContext:DbContext,IShardingDbContext where TEntity : class
{
var entityType = typeof(TEntity);
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
if (!entityType.IsShardingTable())
var virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
var dataSourceNames = new HashSet<string>();
if (!entityType.IsShardingDataSource())
{
var routeTail = routeTailFactory.Create(string.Empty);
var dbContext = shardingDbContext.GetDbContext(true, routeTail);
return new Dictionary<DbContext, IEnumerable<TEntity>>()
{
{dbContext,entities }
};
dataSourceNames.Add(virtualDataSource.DefaultDataSourceName);
}
else
{
var virtualDataSourceRoute = virtualDataSource.GetRoute(entityType);
var allDataSourceNames = virtualDataSourceRoute.GetAllDataSourceNames();
var shardingEntityConfig = ShardingUtil.Parse(entityType);
foreach (var entity in entities)
{
entity.GetPropertyValue(shardingEntityConfig.ShardingDataSourceField)
virtualDataSourceRoute.ShardingKeyToDataSourceName(entity)
dataSourceNames.Add(dataSourceName);
}
}
if (!entityType.IsShardingDataSource())
{
virtualDataSource.
var defaultDataSourceName = virtualDataSource.DefaultDataSourceName;
if (!entityType.IsShardingTable())
{
var routeTail = routeTailFactory.Create(string.Empty);
var dbContext = shardingDbContext.GetDbContext(defaultDataSourceName, true, routeTail);
return new Dictionary<DbContext, IEnumerable<TEntity>>()
{
{dbContext,entities }
};
}
else
{
var virtualTableManager = (IVirtualTableManager)ShardingContainer.GetService(typeof(IVirtualTableManager<>).GetGenericType0(shardingDbContext.ShardingDbContextType));
var virtualTable = virtualTableManager.GetVirtualTable(entityType);
var virtualTableRoute = virtualTable.GetVirtualRoute();
var hashSet = virtualTableRoute.GetAllTails().ToHashSet();
var dic = new Dictionary<string, BulkDicEntry<TEntity>>();
foreach (var entity in entities)
{
var shardingKey = entity.GetPropertyValue(virtualTable.ShardingConfig.ShardingField);
var tail = virtualTableRoute.ShardingKeyToTail(shardingKey);
if (!hashSet.Contains(tail))
throw new ShardingKeyRouteNotMatchException(
$"Entity:{entityType.FullName},ShardingKey:{shardingKey},ShardingTail:{tail}");
var routeTail = routeTailFactory.Create(tail);
var routeTailIdentity = routeTail.GetRouteTailIdentity();
if (!dic.TryGetValue(routeTailIdentity, out var bulkDicEntry))
{
var dbContext = shardingDbContext.GetDbContext(defaultDataSourceName, true, routeTail);
bulkDicEntry = new BulkDicEntry<TEntity>(dbContext, new LinkedList<TEntity>());
dic.Add(routeTailIdentity, bulkDicEntry);
}
bulkDicEntry.InnerEntities.AddLast(entity);
}
return dic.Values.ToDictionary(o => o.InnerDbContext, o => o.InnerEntities.Select(t => t));
}
}
else
{
if (!entityType.IsShardingTable())
{
}
var virtualTableManager = ShardingContainer.GetService<IVirtualTableManager>();
var virtualTable = virtualTableManager.GetVirtualTable(shardingDbContext.ShardingDbContextType, entityType);

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Sharding;
namespace ShardingCore.Extensions
@ -20,11 +21,17 @@ namespace ShardingCore.Extensions
/// <returns></returns>
public static bool IsShardingQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
{
return streamMergeContext.RouteResults.Count() > 1;
return streamMergeContext.TableRouteResults.Count() > 1;
}
public static bool IsSingleShardingTableQuery<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
{
return streamMergeContext.RouteResults.First().ReplaceTables.Count(o => o.EntityType.IsShardingTable()) == 1;
return streamMergeContext.TableRouteResults.First().ReplaceTables.Count(o => o.EntityType.IsShardingTable()) == 1;
}
public static IVirtualTableManager GetVirtualTableManager<TEntity>(this StreamMergeContext<TEntity> streamMergeContext)
{
return (IVirtualTableManager)ShardingContainer.GetService(
typeof(IVirtualTableManager<>).GetGenericType0(streamMergeContext.GetShardingDbContext().GetType()));
}
}
}

View File

@ -7,6 +7,7 @@ using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Core.VirtualTables;
@ -73,10 +74,22 @@ namespace ShardingCore.Extensions
public static string GetTableTail<TEntity>(this IVirtualTableManager virtualTableManager,
TEntity entity) where TEntity : class
{
if (entity.IsShardingTable())
if (!entity.IsShardingTable())
return string.Empty;
var physicTable = virtualTableManager.GetVirtualTable(entity.GetType()).RouteTo(new ShardingTableRouteConfig(null, entity as IShardingTable, null))[0];
return physicTable.Tail;
}
public static bool IsVirtualDataSourceRoute(this Type routeType)
{
if (routeType == null)
throw new ArgumentNullException(nameof(routeType));
return typeof(IVirtualDataSourceRoute).IsAssignableFrom(routeType);
}
public static bool IsIVirtualTableRoute(this Type routeType)
{
if (routeType == null)
throw new ArgumentNullException(nameof(routeType));
return typeof(IVirtualTableRoute).IsAssignableFrom(routeType);
}
}
}

View File

@ -19,11 +19,10 @@ namespace ShardingCore.Extensions
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public static class VirtualDataSourceManagerExtension
public static class VirtualDataSourceExtension
{
public static string GetDataSourceName<TEntity>(this IVirtualDataSourceManager virtualDataSourceManager,TEntity entity) where TEntity : class
public static string GetDataSourceName<TShardingDbContext,TEntity>(this IVirtualDataSource<TShardingDbContext> virtualDataSource,TEntity entity) where TShardingDbContext : DbContext, IShardingDbContext where TEntity : class
{
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource();
if (!entity.IsShardingDataSource())
return virtualDataSource.DefaultDataSourceName;
@ -31,10 +30,10 @@ namespace ShardingCore.Extensions
new ShardingDataSourceRouteConfig(shardingDataSource: entity as IShardingDataSource))[0];
}
public static List<string> GetDataSourceNames<TEntity>(this IVirtualDataSourceManager virtualDataSourceManager,Expression<Func<TEntity, bool>> where)
public static List<string> GetDataSourceNames<TShardingDbContext, TEntity>(this IVirtualDataSource<TShardingDbContext> virtualDataSource, Expression<Func<TEntity, bool>> where)
where TShardingDbContext : DbContext, IShardingDbContext
where TEntity : class
{
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource();
return virtualDataSource.RouteTo(typeof(TEntity),new ShardingDataSourceRouteConfig(predicate: where))
.ToList();
}

View File

@ -106,7 +106,7 @@ namespace ShardingCore.Helpers
//}
}
public static Func<ShardingDbContextOptions, DbContext> CreateActivator<TContext>() where TContext : DbContext, IShardingTableDbContext
public static Func<ShardingDbContextOptions, DbContext> CreateActivator<TContext>() where TContext : DbContext
{
var constructors
= typeof(TContext).GetTypeInfo().DeclaredConstructors
@ -149,7 +149,7 @@ namespace ShardingCore.Helpers
/// <param name="constructor"></param>
/// <param name="paramType"></param>
/// <returns></returns>
private static Func<ShardingDbContextOptions, DbContext> CreateShardingDbContextOptionsActivator<TContext>(ConstructorInfo constructor, Type paramType) where TContext : DbContext, IShardingTableDbContext
private static Func<ShardingDbContextOptions, DbContext> CreateShardingDbContextOptionsActivator<TContext>(ConstructorInfo constructor, Type paramType) where TContext : DbContext
{
var po = Expression.Parameter(paramType, "o");
var newExpression = Expression.New(constructor, po);
@ -168,7 +168,7 @@ namespace ShardingCore.Helpers
/// <param name="constructor"></param>
/// <param name="paramType"></param>
/// <returns></returns>
private static Func<ShardingDbContextOptions, DbContext> CreateDbContextOptionsGenericActivator<TContext>(ConstructorInfo constructor, Type paramType) where TContext : DbContext, IShardingTableDbContext
private static Func<ShardingDbContextOptions, DbContext> CreateDbContextOptionsGenericActivator<TContext>(ConstructorInfo constructor, Type paramType) where TContext : DbContext
{
var parameterExpression = Expression.Parameter(typeof(ShardingDbContextOptions), "o");
//o.DbContextOptions

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore
{
@ -15,11 +17,13 @@ namespace ShardingCore
public interface IShardingConfigOption
{
Type ShardingDbContextType { get;}
Type ActualDbContextType { get;}
bool UseReadWrite { get; }
void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute;
Type GetVirtualRouteType(Type entityType);
Type GetVirtualTableRouteType(Type entityType);
Type GetVirtualDataSourceRouteType(Type entityType);
IDictionary<string, string> GetDataSources();
/// <summary>
@ -34,5 +38,13 @@ namespace ShardingCore
/// 忽略建表时的错误
/// </summary>
public bool? IgnoreCreateTableError { get; set; }
public string DefaultDataSourceName { get; set; }
public string DefaultConnectionString { get; set; }
}
public interface IShardingConfigOption<TShardingDbContext>: IShardingConfigOption where TShardingDbContext : DbContext, IShardingDbContext
{
}
}

View File

@ -20,6 +20,5 @@ namespace ShardingCore
Type ActualDbContextType { get; }
DbContext Creator(ShardingDbContextOptions shardingDbContextOptions);
}
}

View File

@ -45,16 +45,14 @@ namespace ShardingCore.Sharding
public AbstractShardingDbContext(DbContextOptions options) : base(options)
{
ShardingDbContextType = this.GetType();
ActualDbContextType = typeof(TDbContext);
_shardingDbContextExecutor =
(IShardingDbContextExecutor)Activator.CreateInstance(
typeof(ShardingDbContextExecutor<,>).GetGenericType1(ShardingDbContextType, ActualDbContextType));
typeof(ShardingDbContextExecutor<,>).GetGenericType1(this.GetType(), ActualDbContextType));
}
public Type ShardingDbContextType { get; }
public Type ActualDbContextType { get; }
/// <summary>
/// 读写分离优先级

View File

@ -13,11 +13,8 @@ namespace ShardingCore.Sharding.Abstractions
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public interface IConnectionStringManager
public interface IConnectionStringManager<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
string GetConnectionString(string dataSourceName);
}
public interface IConnectionStringManager<TShardingDbContext>: IConnectionStringManager where TShardingDbContext:DbContext,IShardingDbContext
{
}
}

View File

@ -16,10 +16,6 @@ namespace ShardingCore.Sharding.Abstractions
*/
public interface IShardingDbContext
{
/// <summary>
/// 当前sharding的db context type
/// </summary>
Type ShardingDbContextType { get; }
/// <summary>
/// 真实的db context type
/// </summary>

View File

@ -1,16 +1,21 @@
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
namespace ShardingCore.Sharding.Abstractions
{
/*
* @Author: xjm
* @Description:
* @Date: Thursday, 28 January 2021 16:51:41
* @Email: 326308290@qq.com
*/
public interface IStreamMergeContextFactory
/*
* @Author: xjm
* @Description:
* @Date: Thursday, 28 January 2021 16:51:41
* @Email: 326308290@qq.com
*/
public interface IStreamMergeContextFactory
{
StreamMergeContext<T> Create<T>(IQueryable<T> queryable, IShardingDbContext shardingDbContext);
}
public interface IStreamMergeContextFactory<TShardingDbContext> : IStreamMergeContextFactory where TShardingDbContext:DbContext,IShardingDbContext
{
}
}

View File

@ -18,17 +18,17 @@ namespace ShardingCore.Sharding
*/
public class ActualConnectionStringManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly IConnectionStringManager _connectionStringManager;
private readonly IConnectionStringManager<TShardingDbContext> _connectionStringManager;
private readonly IReadWriteOptions<TShardingDbContext> _readWriteOptions;
private readonly bool _useReadWriteSeparation;
private readonly IShardingReadWriteManager _shardingReadWriteManager;
private readonly IVirtualDataSource _virtualDataSource;
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
public int ReadWriteSeparationPriority { get; set; }
public bool ReadWriteSeparation { get; set; }
private string _cacheConnectionString;
public ActualConnectionStringManager()
{
_virtualDataSource=ShardingContainer.GetService<IVirtualDataSourceManager<TShardingDbContext>>().GetVirtualDataSource();
_virtualDataSource=ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
_connectionStringManager = ShardingContainer.GetService<IConnectionStringManager<TShardingDbContext>>();
_readWriteOptions = ShardingContainer.GetService<IReadWriteOptions<TShardingDbContext>>();
_shardingReadWriteManager = ShardingContainer.GetService<IShardingReadWriteManager>();

View File

@ -13,11 +13,11 @@ namespace ShardingCore.Sharding
*/
public class DefaultConnectionStringManager<TShardingDbContext> : IConnectionStringManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly IVirtualDataSource _virtualDataSource;
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
public DefaultConnectionStringManager(IVirtualDataSourceManager<TShardingDbContext> virtualDataSourceManager)
public DefaultConnectionStringManager(IVirtualDataSource<TShardingDbContext> virtualDataSource)
{
_virtualDataSource = virtualDataSourceManager.GetVirtualDataSource();
_virtualDataSource = virtualDataSource;
}
public string GetConnectionString(string dataSourceName)
{

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -16,22 +17,26 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class RandomShardingConnectionStringResolver<TShardingDbContext> :IShardingConnectionStringResolver
public class RandomShardingConnectionStringResolver<TShardingDbContext> : IShardingConnectionStringResolver<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
public Type ShardingDbContextType => typeof(TShardingDbContext);
private readonly string[] _connectionStrings;
private readonly int _length;
public RandomShardingConnectionStringResolver(IEnumerable<string> connectionStrings)
private readonly ConcurrentDictionary<string, ReadWriteRandomConnector> _connectors =
new ConcurrentDictionary<string, ReadWriteRandomConnector>();
public RandomShardingConnectionStringResolver(IEnumerable<ReadWriteRandomConnector> connectors)
{
_connectionStrings = connectionStrings.ToArray();
_length = _connectionStrings.Length;
var enumerator = connectors.GetEnumerator();
while (enumerator.MoveNext())
{
var currentConnector = enumerator.Current;
if (currentConnector != null)
_connectors.TryAdd(currentConnector.DataSourceName, currentConnector);
}
}
public string GetConnectionString()
{
var next = RandomHelper.Next(0, _length);
return _connectionStrings[next];
public string GetConnectionString(string dataSourceName)
{
if (!_connectors.TryGetValue(dataSourceName, out var connector))
throw new InvalidOperationException($"read write connector not found, data source name:[{dataSourceName}]");
return connector.GetConnectionString();
}
}
}

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ShardingCore.Helpers;
namespace ShardingCore.Sharding.ReadWriteConfigurations
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/18 20:58:42
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ReadWriteRandomConnector
{
private readonly string[] _connectionStrings;
private readonly int _length;
public ReadWriteRandomConnector(string dataSourceName,IEnumerable<string> connectionStrings)
{
DataSourceName = dataSourceName;
_connectionStrings = connectionStrings.ToArray();
_length = _connectionStrings.Length;
}
public string GetConnectionString()
{
var next = RandomHelper.Next(0, _length);
return _connectionStrings[next];
}
public string DataSourceName { get; }
}
}

View File

@ -21,6 +21,12 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
{
private readonly ConcurrentDictionary<Type, IShardingReadWriteAccessor> _shardingReadWriteAccessors;
public ShardingReadWriteManager(IEnumerable<IShardingReadWriteAccessor> shardingReadWriteAccessors)
{
_shardingReadWriteAccessors = new ConcurrentDictionary<Type, IShardingReadWriteAccessor>(shardingReadWriteAccessors.ToDictionary(o => o.ShardingDbContextType, o => o));
}
public ShardingReadWriteContext GetCurrent<TShardingDbContext>() where TShardingDbContext : DbContext, IShardingDbContext
{
return GetCurrent(typeof(TShardingDbContext));
@ -36,12 +42,6 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
throw new InvalidOperationException(shardingDbContextType.FullName);
}
public ShardingReadWriteManager(IEnumerable<IShardingReadWriteAccessor> shardingReadWriteAccessors)
{
_shardingReadWriteAccessors = new ConcurrentDictionary<Type,IShardingReadWriteAccessor>(shardingReadWriteAccessors.ToDictionary(o => o.ShardingDbContextType, o => o));
}
public ShardingReadWriteScope<TShardingDbContext> CreateScope<TShardingDbContext>() where TShardingDbContext : DbContext, IShardingDbContext
{
var shardingPageScope = new ShardingReadWriteScope<TShardingDbContext>(_shardingReadWriteAccessors.Values);

View File

@ -1,14 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
@ -18,9 +8,15 @@ using ShardingCore.DbContexts.ShardingDbContexts;
using ShardingCore.Exceptions;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
using ShardingCore.Sharding.ShardingTransactions;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
namespace ShardingCore.Sharding
{
@ -39,9 +35,9 @@ namespace ShardingCore.Sharding
{
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string, DbContext>> _dbContextCaches = new ConcurrentDictionary<string, ConcurrentDictionary<string, DbContext>>();
public IShardingTransaction CurrentShardingTransaction { get; private set; }
private readonly IVirtualDataSourceManager _virtualDataSourceManager;
private readonly IVirtualDataSource<TShardingDbContext> _virtualDataSource;
private readonly IVirtualTableManager _virtualTableManager;
private readonly IShardingDbContextFactory _shardingDbContextFactory;
private readonly IShardingDbContextFactory<TShardingDbContext> _shardingDbContextFactory;
private readonly IShardingDbContextOptionsBuilderConfig _shardingDbContextOptionsBuilderConfig;
private readonly IRouteTailFactory _routeTailFactory;
@ -63,7 +59,7 @@ namespace ShardingCore.Sharding
public ShardingDbContextExecutor()
{
_virtualDataSourceManager = ShardingContainer.GetService<IVirtualDataSourceManager<TShardingDbContext>>();
_virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory<TShardingDbContext>>();
_shardingDbContextOptionsBuilderConfig = ShardingContainer.GetService<IShardingDbContextOptionsBuilderConfig<TShardingDbContext>>();
@ -157,7 +153,7 @@ namespace ShardingCore.Sharding
public DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class
{
var dataSourceName = _virtualDataSourceManager.GetDataSourceName(entity);
var dataSourceName = _virtualDataSource.GetDataSourceName(entity);
var tail = _virtualTableManager.GetTableTail(entity);
return CreateDbContext(true, dataSourceName, _routeTailFactory.Create(tail));
@ -167,7 +163,7 @@ namespace ShardingCore.Sharding
public IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> @where) where TEntity : class
{
var dataSourceNames = _virtualDataSourceManager.GetDataSourceNames(where);
var dataSourceNames = _virtualDataSource.GetDataSourceNames(where);
if (typeof(TEntity).IsShardingTable())
{

View File

@ -14,7 +14,7 @@ namespace ShardingCore.Sharding
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingDbContextOptionsBuilderConfig<TShardingDbContext> : IShardingDbContextOptionsBuilderConfig where TShardingDbContext : DbContext, IShardingDbContext
public class ShardingDbContextOptionsBuilderConfig<TShardingDbContext> : IShardingDbContextOptionsBuilderConfig<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
public ShardingDbContextOptionsBuilderConfig(Action<DbConnection, DbContextOptionsBuilder> sameConnectionDbContextOptionsCreator, Action<string,DbContextOptionsBuilder> defaultQueryDbContextOptionsCreator)
{

View File

@ -24,12 +24,7 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
*/
public class DefaultShardingQueryExecutor : IShardingQueryExecutor
{
private readonly IStreamMergeContextFactory _streamMergeContextFactory;
public DefaultShardingQueryExecutor(IStreamMergeContextFactory streamMergeContextFactory)
{
_streamMergeContextFactory = streamMergeContextFactory;
}
public TResult Execute<TResult>(ICurrentDbContext currentContext, Expression query)
{
var currentDbContext = currentContext.Context;
@ -129,10 +124,15 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
type = type.MakeGenericType(queryEntityType);
var queryable = Activator.CreateInstance(type, query);
var streamMergeContextMethod = _streamMergeContextFactory.GetType().GetMethod("Create");
var streamMergeContextFactory = (IStreamMergeContextFactory)ShardingContainer.GetService(typeof(IStreamMergeContextFactory<>).GetGenericType0(shardingDbContext.GetType()));
// private readonly IStreamMergeContextFactory _streamMergeContextFactory;
var streamMergeContextMethod = streamMergeContextFactory.GetType().GetMethod("Create");
if (streamMergeContextMethod == null)
throw new ShardingCoreException("cant found IStreamMergeContextFactory method [Create]");
var streamMergeContext = streamMergeContextMethod.MakeGenericMethod(new Type[] { queryEntityType }).Invoke(_streamMergeContextFactory, new[] { queryable, shardingDbContext });
var streamMergeContext = streamMergeContextMethod.MakeGenericMethod(new Type[] { queryEntityType }).Invoke(streamMergeContextFactory, new[] { queryable, shardingDbContext });
Type streamMergeEngineType = typeof(AsyncEnumerableStreamMergeEngine<>);

View File

@ -35,7 +35,7 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
{
_streamMergeContext = streamMergeContext;
_shardingPageManager = ShardingContainer.GetService<IShardingPageManager>();
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager>();
_virtualTableManager = streamMergeContext.GetVirtualTableManager();
}
public IEnumeratorStreamMergeEngine<TEntity> ExecuteAsync(CancellationToken cancellationToken = new CancellationToken())
@ -50,8 +50,8 @@ namespace ShardingCore.Sharding.ShardingQueryExecutors
if (_streamMergeContext.IsPaginationQuery() && _streamMergeContext.IsSingleShardingTableQuery() && _shardingPageManager.Current != null)
{
//获取虚拟表判断是否启用了分页配置
var shardingEntityType = _streamMergeContext.RouteResults.First().ReplaceTables.First().EntityType;
var virtualTable = _virtualTableManager.GetVirtualTable(_streamMergeContext.GetShardingDbContext().ShardingDbContextType, shardingEntityType);
var shardingEntityType = _streamMergeContext.TableRouteResults.First().ReplaceTables.First().EntityType;
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntityType);
if (virtualTable.EnablePagination)
{
var paginationMetadata = virtualTable.PaginationMetadata;

View File

@ -7,8 +7,10 @@ using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.Sharding.Abstractions;
using System.Collections.Generic;
using System.Linq;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Extensions;
namespace ShardingCore.Sharding
@ -24,8 +26,6 @@ namespace ShardingCore.Sharding
//private readonly IShardingScopeFactory _shardingScopeFactory;
private readonly IQueryable<T> _source;
private readonly IShardingDbContext _shardingDbContext;
private readonly IDataSourceRouteRuleEngineFactory _dataSourceRouteRuleEngineFactory;
private readonly ITableRouteRuleEngineFactory _tableTableRouteRuleEngineFactory;
private readonly IRouteTailFactory _routeTailFactory;
private readonly IQueryable<T> _reWriteSource;
@ -40,13 +40,14 @@ namespace ShardingCore.Sharding
public IEnumerable<TableRouteResult> TableRouteResults { get; }
public DataSourceRouteResult DataSourceRouteResult { get; }
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext, IDataSourceRouteRuleEngineFactory dataSourceRouteRuleEngineFactory, ITableRouteRuleEngineFactory tableTableRouteRuleEngineFactory, IRouteTailFactory routeTailFactory)
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,
DataSourceRouteResult dataSourceRouteResult,
IEnumerable<TableRouteResult> tableRouteResults,
IRouteTailFactory routeTailFactory)
{
//_shardingScopeFactory = shardingScopeFactory;
_source = source;
_shardingDbContext = shardingDbContext;
_dataSourceRouteRuleEngineFactory = dataSourceRouteRuleEngineFactory;
_tableTableRouteRuleEngineFactory = tableTableRouteRuleEngineFactory;
_routeTailFactory = routeTailFactory;
var reWriteResult = new ReWriteEngine<T>(source).ReWrite();
Skip = reWriteResult.Skip;
@ -55,9 +56,8 @@ namespace ShardingCore.Sharding
SelectContext = reWriteResult.SelectContext;
GroupByContext = reWriteResult.GroupByContext;
_reWriteSource = reWriteResult.ReWriteQueryable;
DataSourceRouteResult =
dataSourceRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
TableRouteResults= _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
DataSourceRouteResult = dataSourceRouteResult;
TableRouteResults= tableRouteResults;
//RouteResults = _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
}
//public StreamMergeContext(IQueryable<T> source,IEnumerable<TableRouteResult> routeResults,
@ -135,5 +135,6 @@ namespace ShardingCore.Sharding
{
return _shardingDbContext;
}
}
}

View File

@ -1,6 +1,7 @@
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.Sharding.Abstractions;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
@ -12,14 +13,14 @@ namespace ShardingCore.Sharding
* @Date: Thursday, 28 January 2021 16:52:43
* @Email: 326308290@qq.com
*/
public class StreamMergeContextFactory:IStreamMergeContextFactory
public class StreamMergeContextFactory<TShardingDbContext> : IStreamMergeContextFactory<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
private readonly IDataSourceRouteRuleEngineFactory _dataSourceRouteRuleEngineFactory;
private readonly ITableRouteRuleEngineFactory _tableRouteRuleEngineFactory;
private readonly IDataSourceRouteRuleEngineFactory<TShardingDbContext> _dataSourceRouteRuleEngineFactory;
private readonly ITableRouteRuleEngineFactory<TShardingDbContext> _tableRouteRuleEngineFactory;
private readonly IRouteTailFactory _routeTailFactory;
public StreamMergeContextFactory(IDataSourceRouteRuleEngineFactory dataSourceRouteRuleEngineFactory,
ITableRouteRuleEngineFactory tableRouteRuleEngineFactory,IRouteTailFactory routeTailFactory)
public StreamMergeContextFactory(IDataSourceRouteRuleEngineFactory<TShardingDbContext> dataSourceRouteRuleEngineFactory,
ITableRouteRuleEngineFactory<TShardingDbContext> tableRouteRuleEngineFactory,IRouteTailFactory routeTailFactory)
{
_dataSourceRouteRuleEngineFactory = dataSourceRouteRuleEngineFactory;
_tableRouteRuleEngineFactory = tableRouteRuleEngineFactory;
@ -27,7 +28,9 @@ namespace ShardingCore.Sharding
}
public StreamMergeContext<T> Create<T>(IQueryable<T> queryable,IShardingDbContext shardingDbContext)
{
return new StreamMergeContext<T>(queryable,shardingDbContext, _dataSourceRouteRuleEngineFactory, _tableRouteRuleEngineFactory, _routeTailFactory);
var dataSourceRouteResult = _dataSourceRouteRuleEngineFactory.Route(queryable);
var tableRouteResults = _tableRouteRuleEngineFactory.Route(queryable);
return new StreamMergeContext<T>(queryable,shardingDbContext, dataSourceRouteResult, tableRouteResults, _routeTailFactory);
}
}
}

View File

@ -57,7 +57,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
}
_mergeContext = ShardingContainer.GetService<IStreamMergeContextFactory>().Create(_queryable, shardingDbContext);
_mergeContext = ((IStreamMergeContextFactory)ShardingContainer.GetService(typeof(IStreamMergeContextFactory<>).GetGenericType0(shardingDbContext.GetType()))).Create(_queryable, shardingDbContext);
_parllelDbbContexts = new List<DbContext>();
}
/// <summary>

View File

@ -38,7 +38,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
{
foreach (var routeQueryResult in result)
{
_shardingPageManager.Current.RouteQueryResults.Add(new RouteQueryResult<long>(routeQueryResult.TableRouteResult, routeQueryResult.QueryResult));
_shardingPageManager.Current.RouteQueryResults.Add(new RouteQueryResult<long>(routeQueryResult.DataSourceName, routeQueryResult.TableRouteResult, routeQueryResult.QueryResult));
}
}
return result.Sum(o=>o.QueryResult);

View File

@ -95,7 +95,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
{
Skip = (int)skip;
Take = (int)take;
DSName = routeQueryResult.DSName;
DSName = routeQueryResult.DataSourceName;
TableRouteResult = routeQueryResult.TableRouteResult;
}

View File

@ -25,13 +25,12 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
public override IStreamMergeAsyncEnumerator<TEntity>[] GetDbStreamMergeAsyncEnumerators(bool async)
{
var dataSourceRouteResult = StreamMergeContext.DataSourceRouteResult;
var enumeratorTasks = dataSourceRouteResult.IntersectDataSources.SelectMany(physicDataSource =>
var enumeratorTasks = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName =>
{
var dsname = physicDataSource.DataSourceName;
var tableRouteResults = StreamMergeContext.GetTableRouteResults(dsname);
var tableRouteResults = StreamMergeContext.TableRouteResults;
return tableRouteResults.Select(routeResult =>
{
var newQueryable = CreateAsyncExecuteQueryable(dsname,routeResult);
var newQueryable = CreateAsyncExecuteQueryable(dataSourceName, routeResult);
return AsyncQueryEnumerator(newQueryable, async);
});

View File

@ -42,12 +42,11 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
var reverseOrderQueryable = noPaginationNoOrderQueryable.Take((int)realSkip+(int)take).OrderWithExpression(propertyOrders);
var dataSourceRouteResult = StreamMergeContext.DataSourceRouteResult;
var enumeratorTasks = dataSourceRouteResult.IntersectDataSources.SelectMany(physicDataSource =>
var enumeratorTasks = dataSourceRouteResult.IntersectDataSources.SelectMany(dataSourceName =>
{
var dsname = physicDataSource.DataSourceName;
return StreamMergeContext.GetTableRouteResults(dsname).Select(routeResult =>
return StreamMergeContext.TableRouteResults.Select(routeResult =>
{
var newQueryable = CreateAsyncExecuteQueryable(dsname,reverseOrderQueryable, routeResult);
var newQueryable = CreateAsyncExecuteQueryable(dataSourceName, reverseOrderQueryable, routeResult);
return AsyncQueryEnumerator(newQueryable, async);
});
}).ToArray();;

View File

@ -20,9 +20,9 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
public override IStreamMergeAsyncEnumerator<TEntity>[] GetDbStreamMergeAsyncEnumerators(bool async)
{
var physicDataSource = StreamMergeContext.DataSourceRouteResult.IntersectDataSources.First();
var routeResult = StreamMergeContext.GetTableRouteResults(physicDataSource.DataSourceName).First();
var shardingDbContext = StreamMergeContext.CreateDbContext(physicDataSource.DataSourceName,routeResult);
var dataSourceName = StreamMergeContext.DataSourceRouteResult.IntersectDataSources.First();
var routeResult = StreamMergeContext.TableRouteResults.First();
var shardingDbContext = StreamMergeContext.CreateDbContext(dataSourceName, routeResult);
DbContextQueryStore.TryAdd(routeResult, shardingDbContext);
var newQueryable = (IQueryable<TEntity>) StreamMergeContext.GetOriginalQueryable().ReplaceDbContextQueryable(shardingDbContext);
if (async)

View File

@ -14,13 +14,13 @@ namespace ShardingCore.Sharding.StreamMergeEngines
*/
public class RouteQueryResult<TResult>
{
public string DSName { get; }
public string DataSourceName { get; }
public TableRouteResult TableRouteResult { get; }
public TResult QueryResult { get; }
public RouteQueryResult(string dsname,TableRouteResult tableRouteResult,TResult queryResult)
public RouteQueryResult(string dataSourceName,TableRouteResult tableRouteResult,TResult queryResult)
{
DSName = dsname;
DataSourceName = dataSourceName;
TableRouteResult = tableRouteResult;
QueryResult = queryResult;
}

View File

@ -27,150 +27,22 @@ namespace ShardingCore
*/
public class ShardingBootstrapper : IShardingBootstrapper
{
private readonly IServiceProvider _serviceProvider;
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions;
private readonly IVirtualTableManager _virtualTableManager;
private readonly IShardingTableCreator _tableCreator;
private readonly ILogger<ShardingBootstrapper> _logger;
private readonly IRouteTailFactory _routeTailFactory;
private readonly IShardingDbContextFactory _shardingDbContextFactory;
public ShardingBootstrapper(IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions,
IVirtualTableManager virtualTableManager
, IShardingTableCreator tableCreator, ILogger<ShardingBootstrapper> logger,
IShardingDbContextFactory shardingDbContextFactory,IRouteTailFactory routeTailFactory)
public ShardingBootstrapper(IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions)
{
ShardingContainer.SetServices(serviceProvider);
_serviceProvider = serviceProvider;
_shardingConfigOptions = shardingConfigOptions;
_virtualTableManager = virtualTableManager;
_tableCreator = tableCreator;
_logger = logger;
_routeTailFactory = routeTailFactory;
_shardingDbContextFactory = shardingDbContextFactory;
}
public void Start()
{
using (var scope = _serviceProvider.CreateScope())
foreach (var shardingConfigOption in _shardingConfigOptions)
{
foreach (var shardingConfigOption in _shardingConfigOptions)
{
using var context =
(DbContext) scope.ServiceProvider.GetService(shardingConfigOption.ShardingDbContextType);
EnsureCreated(context);
foreach (var entity in context.Model.GetEntityTypes())
{
if (entity.ClrType.IsShardingTable())
{
var routeType = shardingConfigOption.GetVirtualRouteType(entity.ClrType);
var virtualRoute = CreateVirtualRoute(routeType);
var virtualTable = CreateVirtualTable(entity.ClrType, virtualRoute);
//获取ShardingEntity的实际表名
var tableName = context.Model.FindEntityType(virtualTable.EntityType).GetTableName();
virtualTable.SetOriginalTableName(tableName);
_virtualTableManager.AddVirtualTable(shardingConfigOption.ShardingDbContextType,virtualTable);
CreateDataTable(shardingConfigOption.ShardingDbContextType,virtualTable, shardingConfigOption);
}
}
}
var instance = (IShardingDbContextBootstrapper)Activator.CreateInstance(typeof(ShardingDbContextBootstrapper<>).GetGenericType0(shardingConfigOption.ShardingDbContextType), shardingConfigOption);
instance.Initialize();
}
}
private IVirtualTableRoute CreateVirtualRoute(Type virtualRouteType)
{
var constructors
= virtualRouteType.GetTypeInfo().DeclaredConstructors
.Where(c => !c.IsStatic && c.IsPublic)
.ToArray();
if (constructors.IsEmpty())
{
object o = Activator.CreateInstance(virtualRouteType);
return (IVirtualTableRoute) o;
}
else
{
if (constructors.Length > 1)
{
throw new ArgumentException(
$"virtual route :[{virtualRouteType}] found more declared constructor ");
}
var @params = constructors[0].GetParameters().Select(x => _serviceProvider.GetService(x.ParameterType))
.ToArray();
object o = Activator.CreateInstance(virtualRouteType, @params);
return (IVirtualTableRoute) o;
}
}
private IVirtualTable CreateVirtualTable(Type entityType, IVirtualTableRoute virtualTableRoute)
{
Type type = typeof(DefaultVirtualTable<>);
type = type.MakeGenericType(entityType);
object o = Activator.CreateInstance(type, virtualTableRoute);
return (IVirtualTable) o;
}
private void EnsureCreated(DbContext context)
{
if (context is IShardingDbContext shardingDbContext)
{
var dbContext = shardingDbContext.GetDbContext(false,_routeTailFactory.Create(string.Empty));
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
lock (modelCacheSyncObject)
{
dbContext.RemoveDbContextRelationModelThatIsShardingTable();
dbContext.Database.EnsureCreated();
dbContext.RemoveModelCache();
}
}
}
private bool NeedCreateTable(ShardingTableConfig config, IShardingConfigOption shardingConfigOption)
{
if (config.AutoCreateTable.HasValue)
{
return config.AutoCreateTable.Value;
}
return shardingConfigOption.CreateShardingTableOnStart.GetValueOrDefault();
}
private void CreateDataTable(Type shardingDbContextType,IVirtualTable virtualTable,IShardingConfigOption shardingConfigOption)
{
var shardingConfig = virtualTable.ShardingConfig;
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
{
if (NeedCreateTable(shardingConfig, shardingConfigOption))
{
try
{
//添加物理表
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
_tableCreator.CreateTable(shardingDbContextType,virtualTable.EntityType, tail);
}
catch (Exception e)
{
if (!shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
{
_logger.LogWarning(
$"table :{virtualTable.GetVirtualTableName()}{shardingConfig.TailPrefix}{tail} will created.",e);
}
}
}
else
{
//添加物理表
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
}
}
}
}
}

View File

@ -1,15 +1,14 @@
using System;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ReadWriteConfigurations;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.EFCores;
using ShardingCore.Sharding;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.Sharding.ReadWriteConfigurations;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Extensions;
namespace ShardingCore
{
@ -20,28 +19,46 @@ namespace ShardingCore
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public class ShardingConfigOption<TShardingDbContext, TActualDbContext> : IShardingConfigOption
where TActualDbContext : DbContext, IShardingTableDbContext
where TShardingDbContext : DbContext, IShardingDbContext<TActualDbContext>
public class ShardingConfigOption<TShardingDbContext> : IShardingConfigOption<TShardingDbContext>
where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly Dictionary<Type, Type> _virtualRoutes = new Dictionary<Type, Type>();
private readonly Dictionary<Type, Type> _virtualDataSourceRoutes = new Dictionary<Type, Type>();
private readonly Dictionary<Type, Type> _virtualTableRoutes = new Dictionary<Type, Type>();
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionConfigure { get;private set; }
public Action<string,DbContextOptionsBuilder> DefaultQueryConfigure { get; private set; }
/// <summary>
/// 配置数据库分表查询和保存时的DbContext创建方式
/// </summary>
/// <param name="sameConnectionConfigure">DbConnection下如何配置因为不同的DbContext支持事务需要使用同一个DbConnection</param>
/// <param name="defaultQueryConfigure">默认查询DbContext创建的配置</param>
public Action<DbConnection, DbContextOptionsBuilder> SameConnectionConfigure { get; private set; }
public Action<string, DbContextOptionsBuilder> DefaultQueryConfigure { get; private set; }
public void UseShardingOptionsBuilder(Action<DbConnection, DbContextOptionsBuilder> sameConnectionConfigure, Action<string,DbContextOptionsBuilder> defaultQueryConfigure = null)
public Func<IServiceProvider, IDictionary<string, string>> DataSourcesConfigure { get; private set; }
public void UseShardingQuery(Action<string, DbContextOptionsBuilder> queryConfigure)
{
SameConnectionConfigure = sameConnectionConfigure ?? throw new ArgumentNullException(nameof(sameConnectionConfigure));
DefaultQueryConfigure = defaultQueryConfigure ?? throw new ArgumentNullException(nameof(defaultQueryConfigure));
DefaultQueryConfigure = queryConfigure ?? throw new ArgumentNullException(nameof(queryConfigure));
}
public void UseShardingTransaction(Action<DbConnection, DbContextOptionsBuilder> transactionConfigure)
{
SameConnectionConfigure = transactionConfigure ?? throw new ArgumentNullException(nameof(transactionConfigure));
}
public void AddShardingDataSource(Func<IServiceProvider, IDictionary<string, string>> dataSourcesConfigure)
{
DataSourcesConfigure = dataSourcesConfigure ?? throw new ArgumentNullException(nameof(dataSourcesConfigure));
}
///// <summary>
///// 配置数据库分表查询和保存时的DbContext创建方式
///// </summary>
///// <param name="sameConnectionConfigure">DbConnection下如何配置因为不同的DbContext支持事务需要使用同一个DbConnection</param>
///// <param name="defaultQueryConfigure">默认查询DbContext创建的配置</param>
//public void UseShardingOptionsBuilder(Action<DbConnection, DbContextOptionsBuilder> sameConnectionConfigure, Action<string,DbContextOptionsBuilder> defaultQueryConfigure = null)
//{
// SameConnectionConfigure = sameConnectionConfigure ?? throw new ArgumentNullException(nameof(sameConnectionConfigure));
// DefaultQueryConfigure = defaultQueryConfigure ?? throw new ArgumentNullException(nameof(defaultQueryConfigure));
//}
public bool UseReadWrite => ReadConnStringConfigure != null;
public Func<IServiceProvider, IEnumerable<string>> ReadConnStringConfigure { get; private set; }
public Func<IServiceProvider, IDictionary<string, ISet<string>>> ReadConnStringConfigure { get; private set; }
public ReadStrategyEnum ReadStrategyEnum { get; private set; }
public bool ReadWriteDefaultEnable { get; private set; }
public int ReadWriteDefaultPriority { get; private set; }
@ -55,7 +72,7 @@ namespace ShardingCore
/// <param name="defaultEnable">考虑到很多时候读写分离的延迟需要马上用到写入的数据所以默认关闭需要的话自己开启或者通过IShardingReadWriteManager,false表示默认不走读写分离除非你自己开启,true表示默认走读写分离除非你禁用,</param>
/// <param name="defaultPriority">IShardingReadWriteManager.CreateScope()会判断dbcontext的priority然后判断是否启用readwrite</param>
/// <param name="readConnStringGetStrategy">读写分离可能会造成每次查询不一样甚至分表后的分页会有错位问题,因为他不是一个原子操作,所以如果整个请求为一次读写切换大多数更加合适</param>
public void UseReadWriteConfiguration(Func<IServiceProvider, IEnumerable<string>> readConnStringConfigure, ReadStrategyEnum readStrategyEnum,bool defaultEnable=false,int defaultPriority=10,ReadConnStringGetStrategyEnum readConnStringGetStrategy= ReadConnStringGetStrategyEnum.LatestFirstTime)
public void UseReadWriteConfiguration(Func<IServiceProvider, IDictionary<string, ISet<string>>> readConnStringConfigure, ReadStrategyEnum readStrategyEnum, bool defaultEnable = false, int defaultPriority = 10, ReadConnStringGetStrategyEnum readConnStringGetStrategy = ReadConnStringGetStrategyEnum.LatestFirstTime)
{
ReadConnStringConfigure = readConnStringConfigure ?? throw new ArgumentNullException(nameof(readConnStringConfigure));
ReadStrategyEnum = readStrategyEnum;
@ -66,8 +83,34 @@ namespace ShardingCore
public Type ShardingDbContextType => typeof(TShardingDbContext);
public Type ActualDbContextType => typeof(TActualDbContext);
/// <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())
throw new InvalidOperationException(routeType.FullName);
//获取类型
var genericVirtualRoute = routeType.GetInterfaces().FirstOrDefault(it => it.IsInterface && it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IVirtualDataSourceRoute<>)
&& it.GetGenericArguments().Any());
if (genericVirtualRoute == null)
throw new ArgumentException("add sharding route type error not assignable from IVirtualDataSourceRoute<>.");
var shardingEntityType = genericVirtualRoute.GetGenericArguments()[0];
if (shardingEntityType == null)
throw new ArgumentException("add sharding table route type error not assignable from IVirtualDataSourceRoute<>");
if (!_virtualDataSourceRoutes.ContainsKey(shardingEntityType))
{
_virtualDataSourceRoutes.Add(shardingEntityType, routeType);
}
}
/// <summary>
/// 添加分表路由
/// </summary>
@ -75,6 +118,12 @@ namespace ShardingCore
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
{
var routeType = typeof(TRoute);
AddShardingTableRoute(routeType);
}
public void AddShardingTableRoute(Type routeType)
{
if (!routeType.IsIVirtualTableRoute())
throw new InvalidOperationException(routeType.FullName);
//获取类型
var genericVirtualRoute = routeType.GetInterfaces().FirstOrDefault(it => it.IsInterface && it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IVirtualTableRoute<>)
&& it.GetGenericArguments().Any());
@ -84,17 +133,29 @@ namespace ShardingCore
var shardingEntityType = genericVirtualRoute.GetGenericArguments()[0];
if (shardingEntityType == null)
throw new ArgumentException("add sharding table route type error not assignable from IVirtualTableRoute<>");
if (!_virtualRoutes.ContainsKey(shardingEntityType))
if (!_virtualTableRoutes.ContainsKey(shardingEntityType))
{
_virtualRoutes.Add(shardingEntityType, routeType);
_virtualTableRoutes.Add(shardingEntityType, routeType);
}
}
public Type GetVirtualRouteType(Type entityType)
public Type GetVirtualTableRouteType(Type entityType)
{
if (!_virtualRoutes.ContainsKey(entityType))
if (!_virtualTableRoutes.ContainsKey(entityType))
throw new ArgumentException($"{entityType} not found IVirtualTableRoute");
return _virtualRoutes[entityType];
return _virtualTableRoutes[entityType];
}
public Type GetVirtualDataSourceRouteType(Type entityType)
{
if (!_virtualDataSourceRoutes.ContainsKey(entityType))
throw new ArgumentException($"{entityType} not found IVirtualDataSourceRoute");
return _virtualDataSourceRoutes[entityType];
}
public IDictionary<string, string> GetDataSources()
{
var defaultDataSources = new Dictionary<string, string>(){{DefaultDataSourceName,DefaultConnectionString}};
return defaultDataSources.Concat(DataSourcesConfigure?.Invoke(ShardingContainer.Services)??new Dictionary<string, string>()).ToDictionary(o=>o.Key,o=>o.Value);
}
@ -113,5 +174,7 @@ namespace ShardingCore
/// </summary>
public bool? IgnoreCreateTableError { get; set; }
public string DefaultDataSourceName { get; set; }
public string DefaultConnectionString { get; set; }
}
}

View File

@ -1,5 +1,11 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore
{
@ -33,15 +39,6 @@ namespace ShardingCore
{
return Services.GetService(serviceType);
}
public static object GetGenericTypeService0(Type genericServiceType,Type genericArg0Type)
{
var serviceType = genericServiceType.MakeGenericType(genericArg0Type);
return GetService(serviceType);
}
public static object GetGenericTypeService1(Type genericServiceType, Type genericArg0Type, Type genericArg1Type)
{
var serviceType = genericServiceType.MakeGenericType(genericArg0Type, genericArg1Type);
return GetService(serviceType);
}
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Version>$(EFCORE5)</Version>

View File

@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ShardingCore.Core.PhysicTables;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
using ShardingCore.Core.VirtualDatabase.VirtualTables;
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualTables;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
using ShardingCore.TableCreator;
namespace ShardingCore
{
/*
* @Author: xjm
* @Description:
* @Date: 2021/9/20 14:04:55
* @Ver: 1.0
* @Email: 326308290@qq.com
*/
public interface IShardingDbContextBootstrapper
{
void Initialize();
}
public class ShardingDbContextBootstrapper<TShardingDbContext>: IShardingDbContextBootstrapper where TShardingDbContext:DbContext,IShardingDbContext
{
private readonly IShardingConfigOption _shardingConfigOption;
private readonly IRouteTailFactory _routeTailFactory;
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
private readonly IShardingTableCreator<TShardingDbContext> _tableCreator;
private readonly ILogger<ShardingDbContextBootstrapper<TShardingDbContext>> _logger;
public ShardingDbContextBootstrapper(IShardingConfigOption shardingConfigOption)
{
_shardingConfigOption = shardingConfigOption;
_routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
_tableCreator=ShardingContainer.GetService<IShardingTableCreator<TShardingDbContext>>();
_logger = ShardingContainer.GetService<ILogger<ShardingDbContextBootstrapper<TShardingDbContext>>>();
}
public void Initialize()
{
var virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
using (var serviceScope = ShardingContainer.Services.CreateScope())
{
var dataSources = _shardingConfigOption.GetDataSources();
virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(_shardingConfigOption.DefaultDataSourceName, _shardingConfigOption.DefaultConnectionString,true));
//foreach (var dataSourceKv in dataSources)
//{
// virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(dataSourceKv.Key,
// dataSourceKv.Value, false));
//}
foreach (var dataSourceKv in dataSources)
{
var dataSourceName = dataSourceKv.Key;
var connectionString = dataSourceKv.Value;
virtualDataSource.AddPhysicDataSource(new DefaultPhysicDataSource(dataSourceName,
connectionString, false));
using var context =
(DbContext)serviceScope.ServiceProvider.GetService(_shardingConfigOption.ShardingDbContextType);
EnsureCreated(context, dataSourceName);
foreach (var entity in context.Model.GetEntityTypes())
{
var entityType = entity.ClrType;
if (entityType.IsShardingDataSource())
{
var routeType = _shardingConfigOption.GetVirtualDataSourceRouteType(entityType);
var virtualRoute = CreateVirtualDataSourceRoute(routeType);
virtualDataSource.AddVirtualDataSourceRoute(virtualRoute);
}
if (entityType.IsShardingTable())
{
var routeType = _shardingConfigOption.GetVirtualTableRouteType(entityType);
var virtualRoute = CreateVirtualTableRoute(routeType);
var virtualTable = CreateVirtualTable(entityType, virtualRoute);
//获取ShardingEntity的实际表名
var tableName = context.Model.FindEntityType(virtualTable.EntityType).GetTableName();
virtualTable.SetOriginalTableName(tableName);
_virtualTableManager.AddVirtualTable(virtualTable);
CreateDataTable(dataSourceName,virtualTable);
}
}
}
}
}
private void EnsureCreated(DbContext context,string dataSourceName)
{
if (context is IShardingDbContext shardingDbContext)
{
var dbContext = shardingDbContext.GetDbContext(dataSourceName,false, _routeTailFactory.Create(string.Empty));
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
lock (modelCacheSyncObject)
{
dbContext.RemoveDbContextRelationModelThatIsShardingTable();
dbContext.Database.EnsureCreated();
dbContext.RemoveModelCache();
}
}
}
private IVirtualDataSourceRoute CreateVirtualDataSourceRoute(Type virtualRouteType)
{
var constructors
= virtualRouteType.GetTypeInfo().DeclaredConstructors
.Where(c => !c.IsStatic && c.IsPublic)
.ToArray();
if (constructors.IsEmpty())
{
object o = Activator.CreateInstance(virtualRouteType);
return (IVirtualDataSourceRoute)o;
}
else
{
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)o;
}
}
private IVirtualTableRoute CreateVirtualTableRoute(Type virtualRouteType)
{
var constructors
= virtualRouteType.GetTypeInfo().DeclaredConstructors
.Where(c => !c.IsStatic && c.IsPublic)
.ToArray();
if (constructors.IsEmpty())
{
object o = Activator.CreateInstance(virtualRouteType);
return (IVirtualTableRoute)o;
}
else
{
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)o;
}
}
private IVirtualTable CreateVirtualTable(Type entityType, IVirtualTableRoute virtualTableRoute)
{
Type type = typeof(DefaultVirtualTable<>);
type = type.MakeGenericType(entityType);
object o = Activator.CreateInstance(type, virtualTableRoute);
return (IVirtualTable)o;
}
private bool NeedCreateTable(ShardingTableConfig config)
{
if (config.AutoCreateTable.HasValue)
{
return config.AutoCreateTable.Value;
}
return _shardingConfigOption.CreateShardingTableOnStart.GetValueOrDefault();
}
private void CreateDataTable(string dataSourceName,IVirtualTable virtualTable)
{
var shardingConfig = virtualTable.ShardingConfig;
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
{
if (NeedCreateTable(shardingConfig))
{
try
{
//添加物理表
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
_tableCreator.CreateTable(dataSourceName,virtualTable.EntityType, tail);
}
catch (Exception e)
{
if (!_shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
{
_logger.LogWarning(
$"table :{virtualTable.GetVirtualTableName()}{shardingConfig.TailPrefix}{tail} will created.", e);
}
}
}
else
{
//添加物理表
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
}
}
}
}
}

View File

@ -6,30 +6,29 @@ using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.TableCreator
{
/*
* @Author: xjm
* @Description:
* @Date: Monday, 21 December 2020 11:22:08
* @Email: 326308290@qq.com
*/
/// <summary>
///
/// </summary>
public interface IShardingTableCreator
/*
* @Author: xjm
* @Description:
* @Date: Monday, 21 December 2020 11:22:08
* @Email: 326308290@qq.com
*/
public interface IShardingTableCreator<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
/// <summary>
/// 创建表
/// </summary>
/// <param name="dataSourceName"></param>
/// <param name="tail"></param>
/// <typeparam name="T"></typeparam>
void CreateTable<TShardingDbContext,T>(string tail) where T : class, IShardingTable where TShardingDbContext:DbContext,IShardingDbContext;
void CreateTable<T>(string dataSourceName, string tail) where T : class, IShardingTable;
/// <summary>
/// 创建表
/// </summary>
/// <param name="shardingDbContextType"></param>
/// <param name="dataSourceName"></param>
/// <param name="shardingEntityType"></param>
/// <param name="tail"></param>
/// <exception cref="ShardingCreateException"></exception>
void CreateTable(Type shardingDbContextType,Type shardingEntityType,string tail);
void CreateTable(string dataSourceName, Type shardingEntityType, string tail);
}
}

View File

@ -23,54 +23,47 @@ namespace ShardingCore.TableCreator
* @Date: Monday, 21 December 2020 11:23:22
* @Email: 326308290@qq.com
*/
public class ShardingTableCreator : IShardingTableCreator
public class ShardingTableCreator<TShardingDbContext> : IShardingTableCreator<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
{
private readonly ILogger<ShardingTableCreator> _logger;
private readonly IShardingDbContextFactory _shardingDbContextFactory;
private readonly IVirtualTableManager _virtualTableManager;
private readonly ILogger<ShardingTableCreator<TShardingDbContext>> _logger;
private readonly IShardingDbContextFactory<TShardingDbContext> _shardingDbContextFactory;
private readonly IVirtualTableManager<TShardingDbContext> _virtualTableManager;
private readonly IServiceProvider _serviceProvider;
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions;
private readonly IShardingConfigOption _shardingConfigOption;
private readonly IRouteTailFactory _routeTailFactory;
public ShardingTableCreator(ILogger<ShardingTableCreator> logger, IShardingDbContextFactory shardingDbContextFactory,
IVirtualTableManager virtualTableManager, IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions,IRouteTailFactory routeTailFactory)
public ShardingTableCreator(ILogger<ShardingTableCreator<TShardingDbContext>> logger, IShardingDbContextFactory<TShardingDbContext> shardingDbContextFactory,
IVirtualTableManager<TShardingDbContext> virtualTableManager, IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions,IRouteTailFactory routeTailFactory)
{
_logger = logger;
_shardingDbContextFactory = shardingDbContextFactory;
_virtualTableManager = virtualTableManager;
_serviceProvider = serviceProvider;
_shardingConfigOptions = shardingConfigOptions;
_shardingConfigOption = shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == typeof(TShardingDbContext))
??throw new ArgumentNullException(typeof(TShardingDbContext).FullName);
_routeTailFactory = routeTailFactory;
}
public void CreateTable<TShardingDbContext, T>(string tail) where TShardingDbContext : DbContext, IShardingDbContext where T : class, IShardingTable
public void CreateTable< T>(string dataSourceName, string tail) where T : class, IShardingTable
{
CreateTable(typeof(TShardingDbContext),typeof(T), tail);
CreateTable(dataSourceName,typeof(T), tail);
}
/// <summary>
///
/// </summary>
/// <param name="shardingDbContextType"></param>
/// <param name="dataSourceName"></param>
/// <param name="shardingEntityType"></param>
/// <param name="tail"></param>
/// <exception cref="ShardingCreateException"></exception>
public void CreateTable(Type shardingDbContextType,Type shardingEntityType, string tail)
public void CreateTable(string dataSourceName,Type shardingEntityType, string tail)
{
if (!shardingDbContextType.IsShardingDbContext())
throw new ShardingCoreException(
$"{shardingDbContextType.FullName} must impl {nameof(IShardingDbContext)}");
var shardingConfigOptions = _shardingConfigOptions.FirstOrDefault(o => o.ShardingDbContextType == shardingDbContextType);
if (shardingConfigOptions == null)
throw new ShardingCoreException(
$"not found sharding config options db context is {shardingDbContextType.FullName}");
using (var serviceScope = _serviceProvider.CreateScope())
{
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntityType);
var dbContext = (DbContext)serviceScope.ServiceProvider.GetService(shardingDbContextType);
var virtualTable = _virtualTableManager.GetVirtualTable( shardingEntityType);
var dbContext = serviceScope.ServiceProvider.GetService<TShardingDbContext>();
var shardingDbContext = (IShardingDbContext)dbContext;
var context = shardingDbContext.GetDbContext(false,_routeTailFactory.Create(tail));
var context = shardingDbContext.GetDbContext(dataSourceName,false, _routeTailFactory.Create(tail));
var modelCacheSyncObject = context.GetModelCacheSyncObject();
@ -84,7 +77,7 @@ namespace ShardingCore.TableCreator
}
catch (Exception ex)
{
if (!shardingConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
if (!_shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
{
_logger.LogWarning(
$"create table error maybe table:[{virtualTable.GetVirtualTableName()}{virtualTable.ShardingConfig.TailPrefix}{tail}]");

View File

@ -29,6 +29,5 @@ namespace ShardingCore.Test50
modelBuilder.ApplyConfiguration(new SysUserSalaryMap());
}
public override Type ShardingDbContextType => this.GetType();
}
}

View File

@ -48,16 +48,17 @@ namespace ShardingCore.Test50
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
{
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"])
,op =>
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o =>
o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]))
.Begin(true)
.AddShardingQuery((conStr, builder) => builder.UseSqlServer(conStr).UseLoggerFactory(efLogger))
.AddShardingTransaction((connection, builder) =>builder.UseSqlServer(connection).UseLoggerFactory(efLogger))
.AddDefaultDataSource("ds0",hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"])
.AddShardingTable(op =>
{
op.EnsureCreatedWithOutShardingTable = true;
op.CreateShardingTableOnStart = true;
op.UseShardingOptionsBuilder((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger),
(conStr,builder)=> builder.UseSqlServer(conStr).UseLoggerFactory(efLogger));
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
});
}).End();
// services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o => o.UseMySql(hostBuilderContext.Configuration.GetSection("MySql")["ConnectionString"],new MySqlServerVersion("5.7.15"))
// ,op =>
// {