第一个测试版本
This commit is contained in:
parent
070a952bfd
commit
4accc08567
|
@ -2,7 +2,7 @@
|
|||
::定义版本
|
||||
set EFCORE2=2.1.0.21
|
||||
set EFCORE3=3.1.0.21
|
||||
set EFCORE5=5.1.0.21
|
||||
set EFCORE5=5.2.0.02
|
||||
|
||||
::删除所有bin与obj下的文件
|
||||
@echo off
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
@ -6,8 +5,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Sample.SqlServer.DbContexts;
|
||||
using Sample.SqlServer.Domain.Entities;
|
||||
using ShardingCore;
|
||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace Sample.SqlServer
|
||||
{
|
||||
|
@ -30,24 +27,24 @@ namespace Sample.SqlServer
|
|||
{
|
||||
using (var scope=app.ApplicationServices.CreateScope())
|
||||
{
|
||||
var virtualDbContext =scope.ServiceProvider.GetService<DefaultTableDbContext>();
|
||||
//if (!virtualDbContext.Set<SysUserMod>().ShardingAny())
|
||||
//{
|
||||
// var ids = Enumerable.Range(1, 1000);
|
||||
// var userMods = new List<SysUserMod>();
|
||||
// foreach (var id in ids)
|
||||
// {
|
||||
// userMods.Add(new SysUserMod()
|
||||
// {
|
||||
// Id = id.ToString(),
|
||||
// Age = id,
|
||||
// Name = $"name_{id}",
|
||||
// });
|
||||
// }
|
||||
var virtualDbContext =scope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
||||
if (!virtualDbContext.Set<SysUserMod>().Any())
|
||||
{
|
||||
var ids = Enumerable.Range(1, 1000);
|
||||
var userMods = new List<SysUserMod>();
|
||||
foreach (var id in ids)
|
||||
{
|
||||
userMods.Add(new SysUserMod()
|
||||
{
|
||||
Id = id.ToString(),
|
||||
Age = id,
|
||||
Name = $"name_{id}",
|
||||
});
|
||||
}
|
||||
|
||||
// virtualDbContext.AddRange(userMods);
|
||||
// virtualDbContext.SaveChanges();
|
||||
//}
|
||||
virtualDbContext.AddRange(userMods);
|
||||
virtualDbContext.SaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,5 +21,6 @@ namespace Sample.SqlServer.DbContexts
|
|||
modelBuilder.ApplyConfiguration(new SysTestMap());
|
||||
}
|
||||
|
||||
public override Type ShardingDbContextType => this.GetType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,4 +5,12 @@
|
|||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Sample.SqlServer.DbContexts;
|
||||
using Sample.SqlServer.Shardings;
|
||||
using ShardingCore;
|
||||
using ShardingCore.EFCores;
|
||||
using ShardingCore.SqlServer;
|
||||
|
||||
namespace Sample.SqlServer
|
||||
{
|
||||
|
@ -30,31 +21,17 @@ namespace Sample.SqlServer
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers();
|
||||
services.AddShardingSqlServer(o =>
|
||||
{
|
||||
o.EnsureCreatedWithOutShardingTable = false;
|
||||
o.CreateShardingTableOnStart = false;
|
||||
o.UseShardingDbContext<DefaultTableDbContext>( dbConfig =>
|
||||
{
|
||||
dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
});
|
||||
//o.AddDataSourceVirtualRoute<>();
|
||||
|
||||
});
|
||||
services.AddDbContext<DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True"));
|
||||
|
||||
|
||||
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(op =>
|
||||
services.AddShardingDbContext<DefaultShardingDbContext, DefaultTableDbContext>(o => o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDBxx;Integrated Security=True;MultipleActiveResultSets=True;")
|
||||
,op =>
|
||||
{
|
||||
op.UseShardingDbContextOptions((connection, builder) =>
|
||||
{
|
||||
return builder.UseSqlServer(connection).UseLoggerFactory(efLogger)
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll)
|
||||
.ReplaceService<IModelCacheKeyFactory, ShardingModelCacheKeyFactory>()
|
||||
.ReplaceService<IModelCustomizer, ShardingModelCustomizer>().Options;
|
||||
op.EnsureCreatedWithOutShardingTable = true;
|
||||
op.CreateShardingTableOnStart = true;
|
||||
op.UseShardingDbContextOptions((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger));
|
||||
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
});
|
||||
},o =>
|
||||
o.UseSqlServer("Data Source=localhost;Initial Catalog=ShardingCoreDB;Integrated Security=True;MultipleActiveResultSets=True;").UseSharding());
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
|
@ -70,7 +47,7 @@ namespace Sample.SqlServer
|
|||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
||||
//app.DbSeed();
|
||||
app.DbSeed();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/3/5 17:30:10
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public abstract class AbstractShardingCoreOptions : IShardingCoreOptions
|
||||
{
|
||||
private ShardingConfigEntry _shardingConfigEntry;
|
||||
|
||||
public void UseShardingDbContext<TContext>(Action<ShardingDbConfigOptions> func) where TContext : DbContext,IShardingTableDbContext
|
||||
{
|
||||
if (_shardingConfigEntry!=null)
|
||||
{
|
||||
throw new ArgumentException($"same db context inited:[{typeof(TContext)}]");
|
||||
}
|
||||
|
||||
ShardingCoreHelper.CheckContextConstructors<TContext>();
|
||||
var creator = ShardingCoreHelper.CreateActivator<TContext>();
|
||||
_shardingConfigEntry = new ShardingConfigEntry(creator, typeof(TContext), func);
|
||||
}
|
||||
|
||||
|
||||
private readonly Dictionary<Type, Type> _virtualRoutes = new Dictionary<Type, Type>();
|
||||
|
||||
|
||||
public ShardingConfigEntry GetShardingConfig()
|
||||
{
|
||||
return _shardingConfigEntry;
|
||||
}
|
||||
|
||||
public ISet<Type> GetVirtualRoutes()
|
||||
{
|
||||
return _virtualRoutes.Select(o => o.Value).ToHashSet();
|
||||
}
|
||||
|
||||
public Type GetVirtualRoute(Type entityType)
|
||||
{
|
||||
if (!_virtualRoutes.ContainsKey(entityType))
|
||||
throw new ArgumentException("not found IDataSourceVirtualRoute");
|
||||
return _virtualRoutes[entityType];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
public bool? CreateShardingTableOnStart { get; set; }
|
||||
|
||||
public readonly List<Type> _filters = new List<Type>();
|
||||
/// <summary>
|
||||
/// 添加filter过滤器
|
||||
/// </summary>
|
||||
/// <typeparam name="TFilter"></typeparam>
|
||||
public void AddDbContextCreateFilter<TFilter>() where TFilter : class, IDbContextCreateFilter
|
||||
{
|
||||
if (_filters.Contains(typeof(TFilter)))
|
||||
throw new ArgumentException("请勿重复添加DbContextCreateFilter");
|
||||
_filters.Add(typeof(TFilter));
|
||||
}
|
||||
|
||||
public List<Type> GetFilters()
|
||||
{
|
||||
return _filters;
|
||||
}
|
||||
|
||||
public bool? IgnoreCreateTableError { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
namespace ShardingCore.Core.ShardingAccessors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Tuesday, 22 December 2020 15:13:44
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingAccessor
|
||||
{
|
||||
ShardingContext ShardingContext { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
namespace ShardingCore.Core.ShardingAccessors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 23 December 2020 07:51:00
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 查询scope创建
|
||||
/// </summary>
|
||||
public interface IShardingScopeFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建查询scope
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ShardingScope CreateScope();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
using System.Threading;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Core.ShardingAccessors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Tuesday, 22 December 2020 15:14:15
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 分表访问器
|
||||
/// </summary>
|
||||
public class ShardingAccessor : IShardingAccessor
|
||||
{
|
||||
private static AsyncLocal<ShardingContext> _shardingContext = new AsyncLocal<ShardingContext>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public ShardingContext ShardingContext
|
||||
{
|
||||
get => _shardingContext.Value;
|
||||
set => _shardingContext.Value = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace ShardingCore.Core.ShardingAccessors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Tuesday, 22 December 2020 15:04:47
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingContext
|
||||
{
|
||||
private ShardingContext(RouteResult routeResult)
|
||||
{
|
||||
foreach (var physicTable in routeResult.ReplaceTables)
|
||||
{
|
||||
_shardingTables.Add(physicTable.VirtualTable, new List<string>(1){physicTable.Tail});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分表操作上下文 key:物理表名 value:虚拟表和本次分表tails
|
||||
/// </summary>
|
||||
private readonly Dictionary<IVirtualTable, List<string>> _shardingTables = new Dictionary<IVirtualTable, List<string>>();
|
||||
|
||||
/// <summary>
|
||||
/// 尝试添加本次操作表
|
||||
/// </summary>
|
||||
/// <param name="virtualTable"></param>
|
||||
/// <param name="tails"></param>
|
||||
/// <returns></returns>
|
||||
public void TryAddShardingTable(IVirtualTable virtualTable, List<string> tails)
|
||||
{
|
||||
_shardingTables.Add(virtualTable, tails);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建一个分表上下文
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ShardingContext Create(RouteResult routeResult)
|
||||
{
|
||||
return new ShardingContext(routeResult);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取分表信息
|
||||
/// </summary>
|
||||
/// <param name="virtualTable"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetContextQueryTails(IVirtualTable virtualTable)
|
||||
{
|
||||
if (_shardingTables.ContainsKey(virtualTable))
|
||||
return _shardingTables[virtualTable] ?? new List<string>(0);
|
||||
return new List<string>(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是空的
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsEmpty()
|
||||
{
|
||||
return _shardingTables.IsEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.Core.ShardingAccessors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 23 December 2020 07:51:30
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingScope : IDisposable
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 分表配置访问器
|
||||
/// </summary>
|
||||
public IShardingAccessor ShardingAccessor { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="shardingAccessor"></param>
|
||||
public ShardingScope(IShardingAccessor shardingAccessor)
|
||||
{
|
||||
ShardingAccessor = shardingAccessor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回收
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
ShardingAccessor.ShardingContext = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
namespace ShardingCore.Core.ShardingAccessors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 23 December 2020 08:11:06
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 分表查询环境创建
|
||||
/// </summary>
|
||||
public class ShardingScopeFactory : IShardingScopeFactory
|
||||
{
|
||||
private readonly IShardingAccessor _shardingAccessor;
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="shardingAccessor"></param>
|
||||
public ShardingScopeFactory(IShardingAccessor shardingAccessor)
|
||||
{
|
||||
_shardingAccessor = shardingAccessor;
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建scope
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ShardingScope CreateScope()
|
||||
{
|
||||
_shardingAccessor.ShardingContext = null;
|
||||
return new ShardingScope(_shardingAccessor);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
|
@ -10,6 +13,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
*/
|
||||
public interface IRouteRuleEngine
|
||||
{
|
||||
IEnumerable<RouteResult> Route<T>(RouteRuleContext<T> routeRuleContext);
|
||||
IEnumerable<RouteResult> Route<T,TShardingDbContext>(RouteRuleContext<T> routeRuleContext) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
IEnumerable<RouteResult> Route<T>(Type shardingDbContextType,RouteRuleContext<T> routeRuleContext);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
|
@ -13,7 +16,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
{
|
||||
IRouteRuleEngine CreateEngine();
|
||||
RouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
|
||||
IEnumerable<RouteResult> Route<T>(IQueryable<T> queryable);
|
||||
IEnumerable<RouteResult> Route<T>(RouteRuleContext<T> ruleContext);
|
||||
IEnumerable<RouteResult> Route<T,TShardingDbContext>(IQueryable<T> queryable) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
IEnumerable<RouteResult> Route<T, TShardingDbContext>(RouteRuleContext<T> ruleContext) where TShardingDbContext : DbContext, IShardingDbContext;
|
||||
IEnumerable<RouteResult> Route<T>(Type shardingDbContextType,IQueryable<T> queryable);
|
||||
IEnumerable<RouteResult> Route<T>(Type shardingDbContextType,RouteRuleContext<T> ruleContext);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
#if !EFCORE5
|
||||
using ShardingCore.Extensions;
|
||||
#endif
|
||||
|
@ -24,30 +28,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(RouteRuleContext<T> routeRuleContext)
|
||||
public IEnumerable<RouteResult> Route<T, TShardingDbContext>(RouteRuleContext<T> routeRuleContext) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
|
||||
var queryEntities = routeRuleContext.Queryable.ParseQueryableRoute();
|
||||
|
||||
|
||||
var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
|
||||
foreach (var shardingEntity in shardingEntities)
|
||||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntity);
|
||||
|
||||
var physicTables = virtualTable.RouteTo(new TableRouteConfig(routeRuleContext.Queryable));
|
||||
if (!routeMaps.ContainsKey(virtualTable))
|
||||
{
|
||||
routeMaps.Add(virtualTable, physicTables.ToHashSet());
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var physicTable in physicTables)
|
||||
{
|
||||
routeMaps[virtualTable].Add(physicTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Route(typeof(TShardingDbContext), routeRuleContext);
|
||||
////先添加手动路由到当前上下文,之后将不再手动路由里面的自动路由添加到当前上下文
|
||||
//foreach (var kv in routeRuleContext.ManualTails)
|
||||
//{
|
||||
|
@ -105,6 +88,32 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(Type shardingDbContextType, RouteRuleContext<T> routeRuleContext)
|
||||
{
|
||||
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
|
||||
var queryEntities = routeRuleContext.Queryable.ParseQueryableRoute();
|
||||
|
||||
|
||||
var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
|
||||
foreach (var shardingEntity in shardingEntities)
|
||||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntity);
|
||||
|
||||
var physicTables = virtualTable.RouteTo(new TableRouteConfig(routeRuleContext.Queryable));
|
||||
if (!routeMaps.ContainsKey(virtualTable))
|
||||
{
|
||||
routeMaps.Add(virtualTable, physicTables.ToHashSet());
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var physicTable in physicTables)
|
||||
{
|
||||
routeMaps[virtualTable].Add(physicTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return routeMaps.Select(o => o.Value).Cartesian().Select(o => new RouteResult(o));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
|
@ -31,17 +34,30 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
return new RouteRuleContext<T>(queryable, _virtualTableManager);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(IQueryable<T> queryable)
|
||||
public IEnumerable<RouteResult> Route<T, TShardingDbContext>(IQueryable<T> queryable) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var engine = CreateEngine();
|
||||
var ruleContext = CreateContext<T>(queryable);
|
||||
return engine.Route(ruleContext);
|
||||
return engine.Route<T,TShardingDbContext>(ruleContext);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(RouteRuleContext<T> ruleContext)
|
||||
public IEnumerable<RouteResult> Route<T, TShardingDbContext>(RouteRuleContext<T> ruleContext) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var engine = CreateEngine();
|
||||
return engine.Route(ruleContext);
|
||||
return engine.Route<T, TShardingDbContext>(ruleContext);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(Type shardingDbContextType, IQueryable<T> queryable)
|
||||
{
|
||||
var engine = CreateEngine();
|
||||
var ruleContext = CreateContext<T>(queryable);
|
||||
return engine.Route(shardingDbContextType,ruleContext);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(Type shardingDbContextType, RouteRuleContext<T> ruleContext)
|
||||
{
|
||||
var engine = CreateEngine();
|
||||
return engine.Route(shardingDbContextType,ruleContext);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualTables
|
||||
{
|
||||
|
@ -18,58 +20,70 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <summary>
|
||||
/// 添加虚拟表应用启动时 add virtual table when app start
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="virtualTable">虚拟表</param>
|
||||
void AddVirtualTable(IVirtualTable virtualTable);
|
||||
void AddVirtualTable(Type shardingDbContextType,IVirtualTable virtualTable);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(Type shardingEntityType);
|
||||
IVirtualTable GetVirtualTable(Type shardingDbContextType, Type shardingEntityType);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IVirtualTable<T> GetVirtualTable<T>() where T : class, IShardingTable;
|
||||
IVirtualTable<T> GetVirtualTable<TDbContext,T>() where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by original table name
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="originalTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(string originalTableName);
|
||||
IVirtualTable GetVirtualTable(Type shardingDbContextType, string originalTableName);
|
||||
IVirtualTable GetVirtualTable<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取虚拟表没有返回null
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="originalTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable TryGetVirtualTable(string originalTableName);
|
||||
IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string originalTableName);
|
||||
IVirtualTable TryGetVirtualTablee<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的虚拟表 get all virtual table
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <returns></returns>
|
||||
List<IVirtualTable> GetAllVirtualTables();
|
||||
List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType);
|
||||
List<IVirtualTable> GetAllVirtualTables<TDbContext>() where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic table
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="virtualTable"></param>
|
||||
/// <param name="physicTable"></param>
|
||||
void AddPhysicTable(IVirtualTable virtualTable, IPhysicTable physicTable);
|
||||
void AddPhysicTable(Type shardingDbContextType,IVirtualTable virtualTable, IPhysicTable physicTable);
|
||||
void AddPhysicTable<TDbContext>(IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic table
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <param name="physicTable"></param>
|
||||
void AddPhysicTable(Type shardingEntityType, IPhysicTable physicTable);
|
||||
void AddPhysicTable(Type shardingDbContextType,Type shardingEntityType, IPhysicTable physicTable);
|
||||
void AddPhysicTable<TDbContext>(Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
///// <summary>
|
||||
///// 添加物理表 add physic table
|
||||
|
|
|
@ -2,8 +2,11 @@ using System;
|
|||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualTables
|
||||
{
|
||||
|
@ -19,8 +22,9 @@ namespace ShardingCore.Core.VirtualTables
|
|||
public class OneDbVirtualTableManager : IVirtualTableManager
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ConcurrentDictionary<Type, IVirtualTable> _shardingVirtualTables = new ConcurrentDictionary<Type, IVirtualTable>();
|
||||
private readonly ConcurrentDictionary<string, IVirtualTable> _shardingOriginalTaleVirtualTales = new ConcurrentDictionary<string, IVirtualTable>();
|
||||
//{sharidngDbContextType:{entityType,virtualTableType}}
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, IVirtualTable>> _shardingVirtualTables = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, IVirtualTable>>();
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, IVirtualTable>> _shardingOriginalTaleVirtualTales = new ConcurrentDictionary<Type, ConcurrentDictionary<string, IVirtualTable>>();
|
||||
public OneDbVirtualTableManager(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
|
@ -38,62 +42,135 @@ namespace ShardingCore.Core.VirtualTables
|
|||
//}
|
||||
}
|
||||
|
||||
public void AddVirtualTable(IVirtualTable virtualTable)
|
||||
private void CheckShardingDbContextType(Type shardingDbContextType)
|
||||
{
|
||||
if (!_shardingVirtualTables.ContainsKey(virtualTable.EntityType))
|
||||
{
|
||||
_shardingVirtualTables.TryAdd(virtualTable.EntityType, virtualTable);
|
||||
if (!shardingDbContextType.IsShardingDbContext())
|
||||
throw new ShardingCoreException(
|
||||
$"{shardingDbContextType.FullName} must impl {nameof(IShardingDbContext)}");
|
||||
}
|
||||
|
||||
if (!_shardingOriginalTaleVirtualTales.ContainsKey(virtualTable.GetOriginalTableName()))
|
||||
private void CheckShardingTableEntityType(Type shardingEntityType)
|
||||
{
|
||||
_shardingOriginalTaleVirtualTales.TryAdd(virtualTable.GetOriginalTableName(), virtualTable);
|
||||
if (!shardingEntityType.IsShardingTable())
|
||||
throw new ShardingCoreException(
|
||||
$"{shardingEntityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
}
|
||||
private string CreateShardingEntityTypeKey(Type shardingDbContextType, Type entityType)
|
||||
{
|
||||
return $"{shardingDbContextType.FullName}{entityType.FullName}";
|
||||
}
|
||||
private string CreateShardingTableNameKey(Type shardingDbContextType, string originalTableName)
|
||||
{
|
||||
return $"{shardingDbContextType.FullName}{originalTableName}";
|
||||
}
|
||||
|
||||
public void AddVirtualTable(Type shardingDbContextType, IVirtualTable virtualTable)
|
||||
{
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
|
||||
var innerShardingVirtualTables = _shardingVirtualTables.GetOrAdd(shardingDbContextType,
|
||||
key => new ConcurrentDictionary<Type, IVirtualTable>());
|
||||
|
||||
if (!innerShardingVirtualTables.ContainsKey(virtualTable.EntityType))
|
||||
{
|
||||
innerShardingVirtualTables.TryAdd(virtualTable.EntityType, virtualTable);
|
||||
}
|
||||
|
||||
var innerShardingOriginalTableVirtualTables = _shardingOriginalTaleVirtualTales.GetOrAdd(shardingDbContextType,type=>new ConcurrentDictionary<string, IVirtualTable>());
|
||||
|
||||
if (!innerShardingOriginalTableVirtualTables.ContainsKey(virtualTable.GetOriginalTableName()))
|
||||
{
|
||||
innerShardingOriginalTableVirtualTables.TryAdd(virtualTable.GetOriginalTableName(), virtualTable);
|
||||
}
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable(Type shardingEntityType)
|
||||
public IVirtualTable GetVirtualTable(Type shardingDbContextType, Type shardingEntityType)
|
||||
{
|
||||
if (!_shardingVirtualTables.TryGetValue(shardingEntityType, out var virtualTable))
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
CheckShardingTableEntityType(shardingEntityType);
|
||||
|
||||
var shardingKey = CreateShardingEntityTypeKey(shardingDbContextType, shardingEntityType);
|
||||
if(!_shardingVirtualTables.TryGetValue(shardingDbContextType,out var innerShardingVirtualTables) || innerShardingVirtualTables.IsEmpty())
|
||||
throw new ShardingVirtualTableNotFoundException(shardingDbContextType.FullName);
|
||||
|
||||
if (!innerShardingVirtualTables.TryGetValue(shardingEntityType, out var virtualTable)||virtualTable==null)
|
||||
throw new ShardingVirtualTableNotFoundException(shardingEntityType.FullName);
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
|
||||
public IVirtualTable<T> GetVirtualTable<T>() where T : class, IShardingTable
|
||||
public IVirtualTable<T> GetVirtualTable<TDbContext, T>() where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return (IVirtualTable<T>)GetVirtualTable(typeof(T));
|
||||
return (IVirtualTable<T>)GetVirtualTable(typeof(TDbContext), typeof(T));
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable(string originalTableName)
|
||||
public IVirtualTable GetVirtualTable(Type shardingDbContextType, string originalTableName)
|
||||
{
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(originalTableName, out var virtualTable)||virtualTable==null)
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(shardingDbContextType, out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
throw new ShardingVirtualTableNotFoundException(shardingDbContextType.FullName);
|
||||
if(!innerShardingOriginalTableVirtualTables.TryGetValue(originalTableName,out var virtualTable)|| virtualTable==null)
|
||||
throw new ShardingVirtualTableNotFoundException(originalTableName);
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTable(string originalTableName)
|
||||
public IVirtualTable GetVirtualTable<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(originalTableName, out var virtualTable))
|
||||
return GetVirtualTable(typeof(TDbContext), originalTableName);
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string originalTableName)
|
||||
{
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(shardingDbContextType,
|
||||
out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
return null;
|
||||
if (!innerShardingOriginalTableVirtualTables.TryGetValue(originalTableName, out var virtualTable) || virtualTable == null)
|
||||
return null;
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public List<IVirtualTable> GetAllVirtualTables()
|
||||
public IVirtualTable TryGetVirtualTablee<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return _shardingVirtualTables.Values.ToList();
|
||||
return TryGetVirtualTable(typeof(TDbContext), originalTableName);
|
||||
}
|
||||
|
||||
public void AddPhysicTable(IVirtualTable virtualTable, IPhysicTable physicTable)
|
||||
public List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType)
|
||||
{
|
||||
AddPhysicTable(virtualTable.EntityType, physicTable);
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(shardingDbContextType,
|
||||
out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
return new List<IVirtualTable>();
|
||||
var keyPrefix = shardingDbContextType.FullName;
|
||||
return innerShardingOriginalTableVirtualTables.Values.ToList();
|
||||
}
|
||||
|
||||
public void AddPhysicTable(Type shardingEntityType, IPhysicTable physicTable)
|
||||
public List<IVirtualTable> GetAllVirtualTables<TDbContext>() where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualTable = GetVirtualTable(shardingEntityType);
|
||||
return GetAllVirtualTables(typeof(TDbContext));
|
||||
}
|
||||
|
||||
public void AddPhysicTable(Type shardingDbContextType, IVirtualTable virtualTable, IPhysicTable physicTable)
|
||||
{
|
||||
AddPhysicTable(shardingDbContextType, virtualTable.EntityType, physicTable);
|
||||
}
|
||||
|
||||
public void AddPhysicTable<TDbContext>(IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
AddPhysicTable(typeof(TDbContext), virtualTable.EntityType, physicTable);
|
||||
}
|
||||
|
||||
|
||||
public void AddPhysicTable(Type shardingDbContextType, Type shardingEntityType, IPhysicTable physicTable)
|
||||
{
|
||||
var virtualTable = GetVirtualTable(shardingDbContextType, shardingEntityType);
|
||||
virtualTable.AddPhysicTable(physicTable);
|
||||
}
|
||||
|
||||
public void AddPhysicTable<TDbContext>(Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualTable = GetVirtualTable(typeof(TDbContext), shardingEntityType);
|
||||
virtualTable.AddPhysicTable(physicTable);
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// 是否是分表字段
|
||||
|
@ -103,7 +180,7 @@ namespace ShardingCore.Core.VirtualTables
|
|||
///// <returns></returns>
|
||||
//public bool IsShardingKey(Type shardingEntityType, string shardingField)
|
||||
//{
|
||||
// return _virtualTables.TryGetValue(shardingEntityType, out var virtualTable) && virtualTable.ShardingConfig.ShardingField == shardingField;
|
||||
// return _virtualTables.TryGetValue(shardingEntityType, out var virtualTable) && virtualTable.ShardingConfigOption.ShardingField == shardingField;
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,17 +1,17 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.Internal.StreamMerge;
|
||||
using ShardingCore.Core.ShardingAccessors;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DbContexts;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.EFCores;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.Sharding;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.TableCreator;
|
||||
using System;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
|
@ -24,9 +24,48 @@ namespace ShardingCore
|
|||
public static class DIExtension
|
||||
{
|
||||
|
||||
public static IServiceCollection AddShardingCore(this IServiceCollection services)
|
||||
|
||||
public static IServiceCollection 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, IShardingTableDbContext<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);
|
||||
|
||||
|
||||
//添加创建TActualDbContext 的 创建者
|
||||
var config = new ShardingDbContextOptionsBuilderConfig<TShardingDbContext>(shardingConfigOptions.ShardingDbContextOptionsCreator);
|
||||
services.AddSingleton<IShardingDbContextOptionsBuilderConfig, ShardingDbContextOptionsBuilderConfig<TShardingDbContext>>(sp=> config);
|
||||
|
||||
//添加创建TActualDbContext创建者
|
||||
services.AddSingleton<IShardingDbContextCreatorConfig,DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>>(sp=> new DefaultShardingDbContextCreatorConfig<TShardingDbContext, TActualDbContext>(typeof(TActualDbContext)));
|
||||
|
||||
|
||||
Action<DbContextOptionsBuilder> shardingOptionAction = option =>
|
||||
{
|
||||
optionsAction?.Invoke(option);
|
||||
option.UseSharding();
|
||||
};
|
||||
services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
|
||||
services.AddInternalShardingCore();
|
||||
|
||||
|
||||
|
||||
services.AddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
|
||||
return services;
|
||||
}
|
||||
|
||||
internal static IServiceCollection AddInternalShardingCore(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IDbContextCreateFilterManager, DbContextCreateFilterManager>();
|
||||
services.AddSingleton<IStreamMergeContextFactory, StreamMergeContextFactory>();
|
||||
|
||||
services.AddSingleton<IShardingDbContextFactory, ShardingDbContextFactory>();
|
||||
|
@ -38,33 +77,20 @@ namespace ShardingCore
|
|||
//分表引擎
|
||||
services.AddSingleton<IRouteRuleEngine, QueryRouteRuleEngines>();
|
||||
//services.AddSingleton(typeof(IVirtualTable<>), typeof(OneDbVirtualTable<>));
|
||||
services.AddSingleton<IShardingAccessor, ShardingAccessor>();
|
||||
services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
|
||||
//services.AddSingleton<IShardingAccessor, ShardingAccessor>();
|
||||
//services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
|
||||
return services;
|
||||
}
|
||||
|
||||
|
||||
public static IServiceCollection AddShardingDbContext<TShardingDbContext, TActualDbContext>(this IServiceCollection services,
|
||||
Action<ShardingConfig<TActualDbContext>> configure,
|
||||
Action<DbContextOptionsBuilder> optionsAction = null,
|
||||
ServiceLifetime contextLifetime = ServiceLifetime.Scoped,
|
||||
ServiceLifetime optionsLifetime = ServiceLifetime.Scoped)
|
||||
where TActualDbContext : DbContext, IShardingTableDbContext
|
||||
where TShardingDbContext : DbContext
|
||||
internal static DbContextOptionsBuilder UseSharding(this DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
if (configure == null)
|
||||
throw new ArgumentNullException($"AddScfSqlServerProvider 参数不能为空:{nameof(configure)}");
|
||||
var shardingConfig = new ShardingConfig<TActualDbContext>();
|
||||
configure?.Invoke(shardingConfig);
|
||||
services.AddSingleton(shardingConfig);
|
||||
|
||||
services.AddDbContext<TShardingDbContext>(optionsAction, contextLifetime, optionsLifetime);
|
||||
services.AddShardingCore();
|
||||
|
||||
|
||||
|
||||
services.AddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
|
||||
return services;
|
||||
return optionsBuilder.ReplaceService<IDbSetSource, ShardingDbSetSource>()
|
||||
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>();
|
||||
}
|
||||
internal static DbContextOptionsBuilder UseInnerDbContextSharding<TShardingDbContext>(this DbContextOptionsBuilder optionsBuilder) where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
return optionsBuilder.ReplaceService<IModelCacheKeyFactory, ShardingModelCacheKeyFactory>()
|
||||
.ReplaceService<IModelCustomizer, ShardingModelCustomizer<TShardingDbContext>>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.DbContexts.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/3/13 8:19:26
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DbContextCreateFilterManager: IDbContextCreateFilterManager
|
||||
{
|
||||
private readonly List<IDbContextCreateFilter> _filters = new List<IDbContextCreateFilter>();
|
||||
public void RegisterFilter(IDbContextCreateFilter filter)
|
||||
{
|
||||
if (null == filter)
|
||||
throw new ArgumentNullException(nameof(filter));
|
||||
if(!_filters.Contains(filter))
|
||||
_filters.Add(filter);
|
||||
}
|
||||
|
||||
public List<IDbContextCreateFilter> GetFilters()
|
||||
{
|
||||
return _filters;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore.DbContexts.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/3/13 8:17:41
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IDbContextCreateFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// dbContext创建完成后
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="s"></param>
|
||||
void CreateAfter(DbContext dbContext);
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ShardingCore.DbContexts.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 12 March 2021 22:25:10
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IDbContextCreateFilterManager
|
||||
{
|
||||
|
||||
void RegisterFilter(IDbContextCreateFilter filter);
|
||||
List<IDbContextCreateFilter> GetFilters();
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ShardingCore.EFCores;
|
||||
|
||||
namespace ShardingCore.DbContexts.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Sunday, 07 February 2021 15:25:36
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingDbContextOptionBuilder
|
||||
{
|
||||
|
||||
private readonly DbContextOptionsBuilder _builder;
|
||||
public ShardingDbContextOptionBuilder():this(new DbContextOptionsBuilder())
|
||||
{
|
||||
|
||||
}
|
||||
public ShardingDbContextOptionBuilder(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
_builder = optionsBuilder
|
||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
|
||||
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>()
|
||||
.ReplaceService<IModelCacheKeyFactory, ShardingModelCacheKeyFactory>()
|
||||
.ReplaceService<IModelCustomizer, ShardingModelCustomizer>();
|
||||
}
|
||||
|
||||
public ShardingDbContextOptionBuilder UseLoggerFactory(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_builder.UseLoggerFactory(loggerFactory);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DbContextOptionsBuilder GetOptionsBuilder()
|
||||
{
|
||||
return _builder;
|
||||
}
|
||||
}
|
||||
public class ShardingDbContextOptionBuilder<T>:ShardingDbContextOptionBuilder where T:DbContext
|
||||
{
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Data.Common;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.DbContexts
|
||||
{
|
||||
|
@ -14,7 +15,8 @@ namespace ShardingCore.DbContexts
|
|||
*/
|
||||
public interface IShardingDbContextFactory
|
||||
{
|
||||
DbContext Create(ShardingDbContextOptions shardingDbContextOptions);
|
||||
DbContext Create(Type shardingDbContextType,ShardingDbContextOptions shardingDbContextOptions);
|
||||
DbContext Create<TShardingDbContext>(ShardingDbContextOptions shardingDbContextOptions) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
//DbContext Create(DbConnection dbConnection,string tail);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore.DbContexts
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Tuesday, 29 December 2020 15:22:06
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingParallelDbContextFactory
|
||||
{
|
||||
DbContext Create(string tail);
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore.DbContexts
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 20 February 2021 15:04:25
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingParallelDbContextFactoryManager
|
||||
{
|
||||
public DbContext CreateDbContext(string connectKey, string tail);
|
||||
}
|
||||
}
|
|
@ -1,14 +1,11 @@
|
|||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ShardingCore.DbContexts
|
||||
{
|
||||
|
@ -20,45 +17,38 @@ namespace ShardingCore.DbContexts
|
|||
*/
|
||||
public class ShardingDbContextFactory:IShardingDbContextFactory
|
||||
{
|
||||
private readonly IShardingCoreOptions _shardingCoreOptions;
|
||||
private readonly IDbContextCreateFilterManager _dbContextCreateFilterManager;
|
||||
private readonly IDbContextOptionsProvider _dbContextOptionsProvider;
|
||||
private readonly IEnumerable<IShardingDbContextCreatorConfig> _shardingDbContextCreatorConfigs;
|
||||
|
||||
public ShardingDbContextFactory(IShardingCoreOptions shardingCoreOptions, IDbContextCreateFilterManager dbContextCreateFilterManager,IDbContextOptionsProvider dbContextOptionsProvider)
|
||||
public ShardingDbContextFactory(IEnumerable<IShardingDbContextCreatorConfig> shardingDbContextCreatorConfigs)
|
||||
{
|
||||
_shardingCoreOptions = shardingCoreOptions;
|
||||
_dbContextCreateFilterManager = dbContextCreateFilterManager;
|
||||
_dbContextOptionsProvider = dbContextOptionsProvider;
|
||||
_shardingDbContextCreatorConfigs = shardingDbContextCreatorConfigs;
|
||||
}
|
||||
public DbContext Create(ShardingDbContextOptions shardingDbContextOptions)
|
||||
public DbContext Create(Type shardingDbContextType, 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 tail=shardingDbContextOptions.Tail;
|
||||
var shardingConfigEntry = _shardingCoreOptions.GetShardingConfig();
|
||||
|
||||
var dbContext = shardingConfigEntry.Creator(shardingDbContextOptions);
|
||||
var dbContext = shardingDbContextCreatorConfig.Creator(shardingDbContextOptions);
|
||||
if (!string.IsNullOrWhiteSpace(tail) && dbContext is IShardingTableDbContext shardingTableDbContext)
|
||||
{
|
||||
shardingTableDbContext.SetShardingTableDbContextTail(tail);
|
||||
}
|
||||
|
||||
var filters = _dbContextCreateFilterManager.GetFilters();
|
||||
if (filters.Any())
|
||||
{
|
||||
foreach (var dbContextCreateFilter in filters)
|
||||
{
|
||||
dbContextCreateFilter.CreateAfter(dbContext);
|
||||
}
|
||||
}
|
||||
var dbContextModel = dbContext.Model;
|
||||
return dbContext;
|
||||
}
|
||||
|
||||
|
||||
//public DbContext Create(DbConnection dbConnection,string tail)
|
||||
//{
|
||||
// var shardingDbContextOptions =
|
||||
// new ShardingDbContextOptions(_dbContextOptionsProvider.GetDbContextOptions(dbConnection), tail);
|
||||
// return Create(shardingDbContextOptions);
|
||||
//}
|
||||
public DbContext Create<TShardingDbContext>(ShardingDbContextOptions shardingDbContextOptions) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return Create(typeof(TShardingDbContext), shardingDbContextOptions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
|
||||
namespace ShardingCore.DbContexts.Transactions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 14 August 2021 04:19:53
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingTransaction:IDisposable
|
||||
{
|
||||
bool IsOpened { get; }
|
||||
bool IsUsed { get; }
|
||||
void Use(DbContext dbContext);
|
||||
void Open();
|
||||
void Rollback();
|
||||
Task RollbackAsync();
|
||||
void Commit();
|
||||
Task CommitAsync();
|
||||
IDbContextTransaction GetDbContextTransaction();
|
||||
}
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using ShardingCore.Exceptions;
|
||||
|
||||
namespace ShardingCore.DbContexts.Transactions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 14 August 2021 04:20:53
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingTransaction: IShardingTransaction
|
||||
{
|
||||
private IDbContextTransaction _dbTransaction;
|
||||
private bool _isOpened;
|
||||
public bool IsOpened => _isOpened;
|
||||
public bool IsUsed => _dbTransaction != null;
|
||||
private readonly ISet<DbContext> _dbContextUseTransactions = new HashSet<DbContext>();
|
||||
|
||||
public void Use(DbContext dbContext)
|
||||
{
|
||||
if (!_isOpened)
|
||||
throw new ShardingTransactionException($"{nameof(ShardingTransaction)} is not open");
|
||||
if (!_dbContextUseTransactions.Contains(dbContext))
|
||||
{
|
||||
if (!IsUsed)
|
||||
_dbTransaction = dbContext.Database.BeginTransaction();
|
||||
else
|
||||
dbContext.Database.UseTransaction(_dbTransaction.GetDbTransaction());
|
||||
_dbContextUseTransactions.Add(dbContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
_isOpened = true;
|
||||
}
|
||||
|
||||
private void Close()
|
||||
{
|
||||
_isOpened = false;
|
||||
_dbContextUseTransactions.Clear();
|
||||
}
|
||||
|
||||
public void Rollback()
|
||||
{
|
||||
_dbTransaction?.Rollback();
|
||||
}
|
||||
|
||||
#if EFCORE2
|
||||
public Task RollbackAsync()
|
||||
{
|
||||
_dbTransaction?.Rollback();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !EFCORE2
|
||||
public async Task RollbackAsync()
|
||||
{
|
||||
if (_dbTransaction != null)
|
||||
await _dbTransaction.RollbackAsync();
|
||||
}
|
||||
#endif
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
_dbTransaction?.Commit();
|
||||
}
|
||||
|
||||
#if EFCORE2
|
||||
public Task CommitAsync()
|
||||
{
|
||||
_dbTransaction?.Commit();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
#endif
|
||||
#if !EFCORE2
|
||||
public async Task CommitAsync()
|
||||
{
|
||||
if (_dbTransaction != null)
|
||||
await _dbTransaction.CommitAsync();
|
||||
}
|
||||
#endif
|
||||
|
||||
public IDbContextTransaction GetDbContextTransaction()
|
||||
{
|
||||
return _dbTransaction;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
_dbTransaction?.Dispose();
|
||||
_dbTransaction = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
using System;
|
||||
using System.Data.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore.DbContexts.VirtualDbContexts
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 24 December 2020 10:32:07
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IDbContextOptionsProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建数据库链接配置
|
||||
/// </summary>
|
||||
/// <param name="dbConnection"></param>
|
||||
/// <returns></returns>
|
||||
DbContextOptions GetDbContextOptions(DbConnection dbConnection);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using ShardingCore.Helpers;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/3/5 17:30:10
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DefaultShardingDbContextCreatorConfig<TShardingDbContext,TActualDbContext> : IShardingDbContextCreatorConfig
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
where TActualDbContext : DbContext, IShardingTableDbContext
|
||||
{
|
||||
private readonly Func<ShardingDbContextOptions, DbContext> _creator;
|
||||
public DefaultShardingDbContextCreatorConfig(Type actualDbContextType)
|
||||
{
|
||||
ActualDbContextType = actualDbContextType;
|
||||
_creator = ShardingCoreHelper.CreateActivator<TActualDbContext>();
|
||||
}
|
||||
|
||||
public Type ShardingDbContextType => typeof(TShardingDbContext);
|
||||
public Type ActualDbContextType { get; }
|
||||
public DbContext Creator(ShardingDbContextOptions shardingDbContextOptions)
|
||||
{
|
||||
return _creator(shardingDbContextOptions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,8 +20,9 @@ namespace ShardingCore.EFCores
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingModelCustomizer: ModelCustomizer
|
||||
public class ShardingModelCustomizer<TShardingDbContext>: ModelCustomizer where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
private Type _shardingDbContextType => typeof(TShardingDbContext);
|
||||
public ShardingModelCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies)
|
||||
{
|
||||
}
|
||||
|
@ -36,7 +37,7 @@ namespace ShardingCore.EFCores
|
|||
if (!string.IsNullOrWhiteSpace(tail))
|
||||
{
|
||||
var virtualTableManager = ShardingContainer.Services.GetService<IVirtualTableManager>();
|
||||
var typeMap = virtualTableManager.GetAllVirtualTables().Where(o => o.GetTaleAllTails().Contains(tail)).Select(o => o.EntityType).ToHashSet();
|
||||
var typeMap = virtualTableManager.GetAllVirtualTables(_shardingDbContextType).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));
|
||||
|
|
|
@ -21,6 +21,32 @@ namespace ShardingCore.Extensions
|
|||
*/
|
||||
public static class CommonExtension
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// IShardingDbContext
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingDbContext(this DbContext dbContext)
|
||||
{
|
||||
if (dbContext == null)
|
||||
throw new ArgumentNullException(nameof(dbContext));
|
||||
return dbContext is IShardingDbContext;
|
||||
}
|
||||
/// <summary>
|
||||
/// IShardingDbContext
|
||||
/// </summary>
|
||||
/// <param name="dbContextType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingDbContext(this Type dbContextType)
|
||||
{
|
||||
if (dbContextType == null)
|
||||
throw new ArgumentNullException(nameof(dbContextType));
|
||||
if (!typeof(DbContext).IsAssignableFrom(dbContextType))
|
||||
return false;
|
||||
return typeof(IShardingDbContext).IsAssignableFrom(dbContextType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IShardingTableDbContext
|
||||
/// </summary>
|
||||
|
@ -41,6 +67,8 @@ namespace ShardingCore.Extensions
|
|||
{
|
||||
if (dbContextType == null)
|
||||
throw new ArgumentNullException(nameof(dbContextType));
|
||||
if (!typeof(DbContext).IsAssignableFrom(dbContextType))
|
||||
return false;
|
||||
return typeof(IShardingTableDbContext).IsAssignableFrom(dbContextType);
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -64,7 +92,7 @@ namespace ShardingCore.Extensions
|
|||
{
|
||||
if (entity == null)
|
||||
throw new ArgumentNullException(nameof(entity));
|
||||
return typeof(IShardingTable).IsAssignableFrom(entity.GetType());
|
||||
return entity is IShardingTable;
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 虚拟表转换成对应的db配置
|
||||
|
@ -73,7 +101,7 @@ namespace ShardingCore.Extensions
|
|||
// /// <returns></returns>
|
||||
// public static List<VirtualTableDbContextConfig> GetVirtualTableDbContextConfigs(this List<IVirtualTable> virtualTables)
|
||||
// {
|
||||
// return virtualTables.Select(o => new VirtualTableDbContextConfig(o.EntityType, o.GetOriginalTableName(), o.ShardingConfig.TailPrefix)).ToList();
|
||||
// return virtualTables.Select(o => new VirtualTableDbContextConfig(o.EntityType, o.GetOriginalTableName(), o.ShardingConfigOption.TailPrefix)).ToList();
|
||||
// }
|
||||
/// <summary>
|
||||
/// 是否是集合contains方法
|
||||
|
|
|
@ -26,9 +26,7 @@ namespace ShardingCore.Extensions
|
|||
/// <returns></returns>
|
||||
public static string GetShardingTableDbContextTail(this IShardingTableDbContext dbContext)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(dbContext.ModelChangeKey))
|
||||
throw new ShardingCoreException($"cant found ModelChangeKey in {dbContext.GetType().FullName}");
|
||||
return dbContext.ModelChangeKey.Replace(ShardingTableDbContextFormat, string.Empty);
|
||||
return dbContext.ModelChangeKey?.Replace(ShardingTableDbContextFormat, string.Empty)??string.Empty;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
|
|
|
@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore;
|
|||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Helpers
|
||||
{
|
||||
|
@ -21,8 +22,10 @@ namespace ShardingCore.Helpers
|
|||
public static int GetStringHashCode(string value)
|
||||
{
|
||||
int h = 0; // 默认值是0
|
||||
if (value.Length > 0) {
|
||||
for (int i = 0; i < value.Length; i++) {
|
||||
if (value.Length > 0)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
h = 31 * h + value[i]; // val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1]
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +106,7 @@ namespace ShardingCore.Helpers
|
|||
//}
|
||||
|
||||
}
|
||||
|
||||
public static Func<ShardingDbContextOptions, DbContext> CreateActivator<TContext>() where TContext : DbContext
|
||||
public static Func<ShardingDbContextOptions, DbContext> CreateActivator<TContext>() where TContext : DbContext, IShardingTableDbContext
|
||||
{
|
||||
var constructors
|
||||
= typeof(TContext).GetTypeInfo().DeclaredConstructors
|
||||
|
@ -147,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
|
||||
private static Func<ShardingDbContextOptions, DbContext> CreateShardingDbContextOptionsActivator<TContext>(ConstructorInfo constructor, Type paramType) where TContext : DbContext, IShardingTableDbContext
|
||||
{
|
||||
var po = Expression.Parameter(paramType, "o");
|
||||
var newExpression = Expression.New(constructor, po);
|
||||
|
@ -166,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
|
||||
private static Func<ShardingDbContextOptions, DbContext> CreateDbContextOptionsGenericActivator<TContext>(ConstructorInfo constructor, Type paramType) where TContext : DbContext, IShardingTableDbContext
|
||||
{
|
||||
var parameterExpression = Expression.Parameter(typeof(ShardingDbContextOptions), "o");
|
||||
//o.DbContextOptions
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/20 6:56:49
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingConfigOption
|
||||
{
|
||||
Type ShardingDbContextType { get;}
|
||||
Type ActualDbContextType { get;}
|
||||
|
||||
void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute;
|
||||
Type GetVirtualRouteType(Type entityType);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
public bool? CreateShardingTableOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
public bool? IgnoreCreateTableError { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/3/4 13:11:16
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingCoreOptions
|
||||
{
|
||||
void UseShardingDbContext<T>(
|
||||
Action<ShardingDbConfigOptions> func) where T : DbContext, IShardingTableDbContext;
|
||||
|
||||
|
||||
|
||||
|
||||
ShardingConfigEntry GetShardingConfig();
|
||||
ISet<Type> GetVirtualRoutes();
|
||||
Type GetVirtualRoute(Type entityType);
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
bool? CreateShardingTableOnStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加filter过滤器
|
||||
/// </summary>
|
||||
/// <typeparam name="TFilter"></typeparam>
|
||||
public void AddDbContextCreateFilter<TFilter>() where TFilter : class, IDbContextCreateFilter;
|
||||
|
||||
public List<Type> GetFilters();
|
||||
|
||||
bool? IgnoreCreateTableError { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/3/4 13:11:16
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingDbContextCreatorConfig
|
||||
{
|
||||
Type ShardingDbContextType { get; }
|
||||
Type ActualDbContextType { get; }
|
||||
|
||||
DbContext Creator(ShardingDbContextOptions shardingDbContextOptions);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/20 11:34:55
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingDbContextOptionsBuilderConfig
|
||||
{
|
||||
Type ShardingDbContextType { get; }
|
||||
DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -30,13 +31,13 @@ namespace ShardingCore.Sharding
|
|||
/// 分表分库的dbcontext
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class AbstractShardingDbContext<T> : DbContext, IShardingDbContext where T : DbContext, IShardingTableDbContext
|
||||
public abstract class AbstractShardingDbContext<T> : DbContext, IShardingTableDbContext<T> where T : DbContext, IShardingTableDbContext
|
||||
{
|
||||
private readonly string EMPTY_SHARDING_TAIL_ID = Guid.NewGuid().ToString("n");
|
||||
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||
private readonly ShardingConfig<T> _shardingConfig;
|
||||
private readonly IShardingDbContextOptionsBuilderConfig _shardingDbContextOptionsBuilderConfig;
|
||||
private DbContextOptions<T> _dbContextOptions;
|
||||
|
||||
private readonly object CREATELOCK = new object();
|
||||
|
@ -45,10 +46,13 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory>();
|
||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager>();
|
||||
_shardingConfig = ShardingContainer.GetService<ShardingConfig<T>>();
|
||||
_shardingDbContextOptionsBuilderConfig = ShardingContainer
|
||||
.GetService<IEnumerable<IShardingDbContextOptionsBuilderConfig>>()
|
||||
.FirstOrDefault(o => o.ShardingDbContextType == ShardingDbContextType);
|
||||
|
||||
}
|
||||
|
||||
public abstract Type ShardingDbContextType { get; }
|
||||
public Type ActualDbContextType => typeof(T);
|
||||
|
||||
|
||||
|
@ -64,8 +68,8 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||
var dbConnection = Database.GetDbConnection();
|
||||
dbConnection.Open();
|
||||
return _shardingConfig.ShardingDbContextOptionsCreator(dbConnection, dbContextOptionBuilder);
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
||||
return dbContextOptionBuilder.Options;
|
||||
}
|
||||
|
||||
private ShardingDbContextOptions CreateSameShardingDbContextOptions(string tail)
|
||||
|
@ -87,7 +91,7 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
if (!_dbContextCaches.TryGetValue(tail, out var dbContext))
|
||||
{
|
||||
dbContext = _shardingDbContextFactory.Create(CreateSameShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
||||
dbContext = _shardingDbContextFactory.Create(ShardingDbContextType,CreateSameShardingDbContextOptions(tail == EMPTY_SHARDING_TAIL_ID ? string.Empty : tail));
|
||||
_dbContextCaches.TryAdd(tail, dbContext);
|
||||
}
|
||||
|
||||
|
@ -101,13 +105,25 @@ namespace ShardingCore.Sharding
|
|||
var tail = EMPTY_SHARDING_TAIL_ID;
|
||||
if (entity.IsShardingTable())
|
||||
{
|
||||
var physicTable = _virtualTableManager.GetVirtualTable(entity.GetType()).RouteTo(new TableRouteConfig(null, entity as IShardingTable, null))[0];
|
||||
var physicTable = _virtualTableManager.GetVirtualTable(ShardingDbContextType,entity.GetType()).RouteTo(new TableRouteConfig(null, entity as IShardingTable, null))[0];
|
||||
tail = physicTable.Tail;
|
||||
}
|
||||
|
||||
return GetDbContext(true, tail);
|
||||
}
|
||||
|
||||
public bool TryOpen()
|
||||
{
|
||||
var dbConnection = Database.GetDbConnection();
|
||||
if (dbConnection.State != ConnectionState.Open)
|
||||
{
|
||||
dbConnection.Open();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override EntityEntry Add(object entity)
|
||||
{
|
||||
return CreateGenericDbContext(entity).Add(entity);
|
||||
|
@ -380,13 +396,15 @@ namespace ShardingCore.Sharding
|
|||
finally
|
||||
{
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
Database.CurrentTransaction?.Dispose();
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
dbContextCache.Value.Database.UseTransaction(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -415,13 +433,14 @@ namespace ShardingCore.Sharding
|
|||
finally
|
||||
{
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
Database.CurrentTransaction?.Dispose();
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
dbContextCache.Value.Database.UseTransaction(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -451,13 +470,15 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
if (!isBeginTransaction) { }
|
||||
if (Database.CurrentTransaction != null)
|
||||
{
|
||||
await Database.CurrentTransaction.DisposeAsync();
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -487,6 +508,7 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
if (!isBeginTransaction)
|
||||
if (Database.CurrentTransaction != null)
|
||||
{
|
||||
await Database.CurrentTransaction.DisposeAsync();
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
|
@ -494,6 +516,8 @@ namespace ShardingCore.Sharding
|
|||
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
*/
|
||||
public interface IShardingDbContext
|
||||
{
|
||||
Type ShardingDbContextType { get; }
|
||||
/// <summary>
|
||||
/// 真实的DbContext 类型
|
||||
/// </summary>
|
||||
|
@ -20,7 +21,7 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
/// <summary>
|
||||
/// 创建DbContext
|
||||
/// </summary>
|
||||
/// <param name="track"></param>
|
||||
/// <param name="track">true表示创建的dbcontext挂在当前的shardingdbcontext下无需管理生命周期,false需要手动释放,true not care dbcontext life, false need call dispose()</param>
|
||||
/// <param name="tail"></param>
|
||||
/// <returns></returns>
|
||||
DbContext GetDbContext(bool track,string tail);
|
||||
|
@ -33,5 +34,12 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
DbContext CreateGenericDbContext<T>(T entity) where T : class;
|
||||
|
||||
|
||||
bool TryOpen();
|
||||
|
||||
}
|
||||
|
||||
public interface IShardingTableDbContext<T> : IShardingDbContext where T : DbContext, IShardingTableDbContext
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ShardingCore.Sharding.Abstractions
|
||||
{
|
||||
|
|
|
@ -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.Sharding
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/19 20:57:52
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingDbContextOptionsBuilderConfig<TShardingDbContext> : IShardingDbContextOptionsBuilderConfig where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
public ShardingDbContextOptionsBuilderConfig(Action<DbConnection, DbContextOptionsBuilder> shardingDbContextOptionsCreator)
|
||||
{
|
||||
ShardingDbContextOptionsCreator = shardingDbContextOptionsCreator;
|
||||
}
|
||||
public Action<DbConnection, DbContextOptionsBuilder> ShardingDbContextOptionsCreator { get; }
|
||||
public Type ShardingDbContextType => typeof(TShardingDbContext);
|
||||
|
||||
public DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection, DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
ShardingDbContextOptionsCreator(dbConnection, dbContextOptionsBuilder);
|
||||
dbContextOptionsBuilder.UseInnerDbContextSharding<TShardingDbContext>();
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.Internal.StreamMerge.ReWrite;
|
||||
using ShardingCore.Core.Internal.Visitors;
|
||||
using ShardingCore.Core.Internal.Visitors.GroupBys;
|
||||
using ShardingCore.Core.Internal.Visitors.Selects;
|
||||
using ShardingCore.Core.ShardingAccessors;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.DbContexts;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
|
@ -21,7 +19,6 @@ namespace ShardingCore.Sharding
|
|||
*/
|
||||
public class StreamMergeContext<T>
|
||||
{
|
||||
private readonly IShardingParallelDbContextFactory _shardingParallelDbContextFactory;
|
||||
//private readonly IShardingScopeFactory _shardingScopeFactory;
|
||||
private readonly IQueryable<T> _source;
|
||||
private readonly IShardingDbContext _shardingDbContext;
|
||||
|
@ -37,10 +34,8 @@ namespace ShardingCore.Sharding
|
|||
public SelectContext SelectContext { get;}
|
||||
public GroupByContext GroupByContext { get; }
|
||||
|
||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory,
|
||||
IShardingParallelDbContextFactory shardingParallelDbContextFactory,IShardingScopeFactory shardingScopeFactory)
|
||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory)
|
||||
{
|
||||
_shardingParallelDbContextFactory = shardingParallelDbContextFactory;
|
||||
//_shardingScopeFactory = shardingScopeFactory;
|
||||
_source = source;
|
||||
_shardingDbContext = shardingDbContext;
|
||||
|
@ -69,13 +64,17 @@ namespace ShardingCore.Sharding
|
|||
// _reWriteSource = reWriteResult.ReWriteQueryable;
|
||||
//}
|
||||
|
||||
public bool TryOpen()
|
||||
{
|
||||
return _shardingDbContext.TryOpen();
|
||||
}
|
||||
public DbContext CreateDbContext(string tail)
|
||||
{
|
||||
return _shardingDbContext.GetDbContext(true,tail);
|
||||
}
|
||||
public IEnumerable<RouteResult> GetRouteResults()
|
||||
{
|
||||
return _tableRoutingRuleEngineFactory.Route(_source);
|
||||
return _tableRoutingRuleEngineFactory.Route(_shardingDbContext.GetType(),_source);
|
||||
}
|
||||
|
||||
//public ShardingScope CreateScope()
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using System.Linq;
|
||||
using ShardingCore.Core.ShardingAccessors;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.DbContexts;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System.Linq;
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
{
|
||||
|
@ -14,21 +12,16 @@ namespace ShardingCore.Sharding
|
|||
*/
|
||||
public class StreamMergeContextFactory:IStreamMergeContextFactory
|
||||
{
|
||||
private readonly IShardingParallelDbContextFactory _shardingParallelDbContextFactory;
|
||||
private readonly IShardingScopeFactory _shardingScopeFactory;
|
||||
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
||||
|
||||
public StreamMergeContextFactory(IShardingParallelDbContextFactory shardingParallelDbContextFactory,
|
||||
IShardingScopeFactory shardingScopeFactory,
|
||||
public StreamMergeContextFactory(
|
||||
IRoutingRuleEngineFactory routingRuleEngineFactory)
|
||||
{
|
||||
_shardingParallelDbContextFactory = shardingParallelDbContextFactory;
|
||||
_shardingScopeFactory = shardingScopeFactory;
|
||||
_routingRuleEngineFactory = routingRuleEngineFactory;
|
||||
}
|
||||
public StreamMergeContext<T> Create<T>(IQueryable<T> queryable,IShardingDbContext shardingDbContext)
|
||||
{
|
||||
return new StreamMergeContext<T>(queryable,shardingDbContext, _routingRuleEngineFactory, _shardingParallelDbContextFactory, _shardingScopeFactory);
|
||||
return new StreamMergeContext<T>(queryable,shardingDbContext, _routingRuleEngineFactory);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -46,6 +46,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
|||
}
|
||||
|
||||
_mergeContext = ShardingContainer.GetService<IStreamMergeContextFactory>().Create(_queryable, shardingDbContext);
|
||||
_mergeContext.TryOpen();
|
||||
}
|
||||
|
||||
protected abstract IQueryable<TEntity> ProcessSecondExpression(IQueryable<TEntity> queryable, Expression secondExpression);
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
@ -12,6 +13,7 @@ using ShardingCore.Core.VirtualTables;
|
|||
using ShardingCore.DbContexts;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.TableCreator;
|
||||
|
||||
namespace ShardingCore
|
||||
|
@ -25,53 +27,42 @@ namespace ShardingCore
|
|||
public class ShardingBootstrapper : IShardingBootstrapper
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IShardingCoreOptions _shardingCoreOptions;
|
||||
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions;
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
private readonly IShardingTableCreator _tableCreator;
|
||||
private readonly ILogger<ShardingBootstrapper> _logger;
|
||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||
private readonly IDbContextCreateFilterManager _dbContextCreateFilterManager;
|
||||
|
||||
public ShardingBootstrapper(IServiceProvider serviceProvider, IShardingCoreOptions shardingCoreOptions,
|
||||
public ShardingBootstrapper(IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions,
|
||||
IVirtualTableManager virtualTableManager
|
||||
, IShardingTableCreator tableCreator, ILogger<ShardingBootstrapper> logger,
|
||||
IShardingDbContextFactory shardingDbContextFactory,IDbContextCreateFilterManager dbContextCreateFilterManager)
|
||||
IShardingDbContextFactory shardingDbContextFactory)
|
||||
{
|
||||
ShardingContainer.SetServices(serviceProvider);
|
||||
_serviceProvider = serviceProvider;
|
||||
_shardingCoreOptions = shardingCoreOptions;
|
||||
_shardingConfigOptions = shardingConfigOptions;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_tableCreator = tableCreator;
|
||||
_logger = logger;
|
||||
_shardingDbContextFactory = shardingDbContextFactory;
|
||||
_dbContextCreateFilterManager = dbContextCreateFilterManager;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
foreach (var filter in _shardingCoreOptions.GetFilters())
|
||||
|
||||
|
||||
using (var scope = _serviceProvider.CreateScope())
|
||||
{
|
||||
_dbContextCreateFilterManager.RegisterFilter((IDbContextCreateFilter)Activator.CreateInstance(filter));
|
||||
}
|
||||
|
||||
|
||||
var shardingConfig= _shardingCoreOptions.GetShardingConfig();
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
using var context =(DbContext)scope.ServiceProvider.GetService(shardingConfig.DbContextType);
|
||||
#if EFCORE5
|
||||
shardingConfig.ConnectionString = context.Database.GetConnectionString();
|
||||
#endif
|
||||
#if !EFCORE5
|
||||
shardingConfig.ConnectionString = context.Database.GetDbConnection().ConnectionString;
|
||||
#endif
|
||||
|
||||
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 = shardingConfig.DbConfigOptions.GetVirtualRoute(entity.ClrType);
|
||||
var routeType = shardingConfigOption.GetVirtualRouteType(entity.ClrType);
|
||||
var virtualRoute = CreateVirtualRoute(routeType);
|
||||
var virtualTable = CreateVirtualTable(entity.ClrType, virtualRoute);
|
||||
|
||||
|
@ -83,8 +74,11 @@ namespace ShardingCore
|
|||
var tableName = context.Model.FindEntityType(virtualTable.EntityType).Relational().TableName;
|
||||
#endif
|
||||
virtualTable.SetOriginalTableName(tableName);
|
||||
_virtualTableManager.AddVirtualTable(virtualTable);
|
||||
CreateDataTable(virtualTable);
|
||||
_virtualTableManager.AddVirtualTable(shardingConfigOption.ShardingDbContextType,virtualTable);
|
||||
CreateDataTable(shardingConfigOption.ShardingDbContextType,virtualTable, shardingConfigOption);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,48 +120,49 @@ namespace ShardingCore
|
|||
|
||||
private void EnsureCreated(DbContext context)
|
||||
{
|
||||
if (_shardingCoreOptions.EnsureCreatedWithOutShardingTable)
|
||||
if (context is IShardingDbContext shardingDbContext)
|
||||
{
|
||||
var modelCacheSyncObject = context.GetModelCacheSyncObject();
|
||||
var dbContext = shardingDbContext.GetDbContext(true,string.Empty);
|
||||
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
|
||||
|
||||
lock (modelCacheSyncObject)
|
||||
{
|
||||
context.RemoveDbContextRelationModelThatIsShardingTable();
|
||||
context.Database.EnsureCreated();
|
||||
context.RemoveModelCache();
|
||||
dbContext.RemoveDbContextRelationModelThatIsShardingTable();
|
||||
dbContext.Database.EnsureCreated();
|
||||
dbContext.RemoveModelCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool NeedCreateTable(ShardingTableConfig config)
|
||||
private bool NeedCreateTable(ShardingTableConfig config, IShardingConfigOption shardingConfigOption)
|
||||
{
|
||||
if (config.AutoCreateTable.HasValue)
|
||||
{
|
||||
return config.AutoCreateTable.Value;
|
||||
}
|
||||
|
||||
return _shardingCoreOptions.CreateShardingTableOnStart.GetValueOrDefault();
|
||||
return shardingConfigOption.CreateShardingTableOnStart.GetValueOrDefault();
|
||||
}
|
||||
|
||||
private void CreateDataTable(IVirtualTable virtualTable)
|
||||
private void CreateDataTable(Type shardingDbContextType,IVirtualTable virtualTable,IShardingConfigOption shardingConfigOption)
|
||||
{
|
||||
var shardingConfig = virtualTable.ShardingConfig;
|
||||
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
|
||||
{
|
||||
if (NeedCreateTable(shardingConfig))
|
||||
if (NeedCreateTable(shardingConfig, shardingConfigOption))
|
||||
{
|
||||
try
|
||||
{
|
||||
//添加物理表
|
||||
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
|
||||
_tableCreator.CreateTable(virtualTable.EntityType, tail);
|
||||
_tableCreator.CreateTable(shardingDbContextType,virtualTable.EntityType, tail);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
if (!_shardingCoreOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||
if (!shardingConfigOption.IgnoreCreateTableError.GetValueOrDefault())
|
||||
{
|
||||
_logger.LogWarning(
|
||||
$"table :{virtualTable.GetOriginalTableName()}{shardingConfig.TailPrefix}{tail} will created");
|
||||
$"table :{virtualTable.GetOriginalTableName()}{shardingConfig.TailPrefix}{tail} will created.",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/16 15:18:37
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingConfig<T> where T:DbContext,IShardingTableDbContext
|
||||
{
|
||||
|
||||
public Func<DbConnection, DbContextOptionsBuilder<T>, DbContextOptions<T>> ShardingDbContextOptionsCreator { get; private set; }
|
||||
public void UseShardingDbContextOptions(Func<DbConnection, DbContextOptionsBuilder<T>, DbContextOptions<T>> shardingDbContextOptions)
|
||||
{
|
||||
ShardingDbContextOptionsCreator = shardingDbContextOptions ?? throw new ArgumentNullException(nameof(shardingDbContextOptions));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
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;
|
||||
|
||||
namespace ShardingCore
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/16 15:18:37
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingConfigOption<TShardingDbContext, TActualDbContext> : IShardingConfigOption
|
||||
where TActualDbContext : DbContext, IShardingTableDbContext
|
||||
where TShardingDbContext : DbContext, IShardingTableDbContext<TActualDbContext>
|
||||
{
|
||||
private readonly Dictionary<Type, Type> _virtualRoutes = new Dictionary<Type, Type>();
|
||||
|
||||
public Action<DbConnection, DbContextOptionsBuilder> ShardingDbContextOptionsCreator { get; set; }
|
||||
public void UseShardingDbContextOptions(Action<DbConnection, DbContextOptionsBuilder> shardingDbContextOptionsCreator)
|
||||
{
|
||||
ShardingDbContextOptionsCreator = shardingDbContextOptionsCreator ?? throw new ArgumentNullException(nameof(shardingDbContextOptionsCreator));
|
||||
}
|
||||
|
||||
|
||||
public Type ShardingDbContextType => typeof(TShardingDbContext);
|
||||
public Type ActualDbContextType => typeof(TActualDbContext);
|
||||
|
||||
/// <summary>
|
||||
/// 添加分表路由
|
||||
/// </summary>
|
||||
/// <typeparam name="TRoute"></typeparam>
|
||||
public void AddShardingTableRoute<TRoute>() where TRoute : IVirtualTableRoute
|
||||
{
|
||||
var routeType = typeof(TRoute);
|
||||
//获取类型
|
||||
var genericVirtualRoute = routeType.GetInterfaces().FirstOrDefault(it => it.IsInterface && it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IVirtualTableRoute<>)
|
||||
&& it.GetGenericArguments().Any());
|
||||
if (genericVirtualRoute == null)
|
||||
throw new ArgumentException("add sharding route type error not assignable from IVirtualTableRoute<>.");
|
||||
|
||||
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))
|
||||
{
|
||||
_virtualRoutes.Add(shardingEntityType, routeType);
|
||||
}
|
||||
}
|
||||
|
||||
public Type GetVirtualRouteType(Type entityType)
|
||||
{
|
||||
if (!_virtualRoutes.ContainsKey(entityType))
|
||||
throw new ArgumentException($"{entityType} not found IVirtualTableRoute");
|
||||
return _virtualRoutes[entityType];
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
/// </summary>
|
||||
public bool EnsureCreatedWithOutShardingTable { get; set; }
|
||||
/// <summary>
|
||||
/// 是否需要在启动时创建分表
|
||||
/// </summary>
|
||||
public bool? CreateShardingTableOnStart { get; set; }
|
||||
/// <summary>
|
||||
/// 忽略建表时的错误
|
||||
/// </summary>
|
||||
public bool? IgnoreCreateTableError { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -29,5 +29,9 @@ namespace ShardingCore
|
|||
{
|
||||
return Services.GetService<T>();
|
||||
}
|
||||
public static object GetService(Type serviceType)
|
||||
{
|
||||
return Services.GetService(serviceType);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.TableCreator
|
||||
{
|
||||
|
@ -20,13 +22,14 @@ namespace ShardingCore.TableCreator
|
|||
/// </summary>
|
||||
/// <param name="tail"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
void CreateTable<T>(string tail) where T : class, IShardingTable;
|
||||
void CreateTable<TShardingDbContext,T>(string tail) where T : class, IShardingTable where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
/// <summary>
|
||||
/// 创建表
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType"></param>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <param name="tail"></param>
|
||||
/// <exception cref="ShardingCreateException"></exception>
|
||||
void CreateTable(Type shardingEntityType,string tail);
|
||||
void CreateTable(Type shardingDbContextType,Type shardingEntityType,string tail);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
@ -7,10 +9,12 @@ using Microsoft.Extensions.Logging;
|
|||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DbContexts;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.TableCreator
|
||||
{
|
||||
|
@ -26,50 +30,60 @@ namespace ShardingCore.TableCreator
|
|||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly IShardingCoreOptions _shardingCoreOptions;
|
||||
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions;
|
||||
|
||||
public ShardingTableCreator(ILogger<ShardingTableCreator> logger, IShardingDbContextFactory shardingDbContextFactory,
|
||||
IVirtualTableManager virtualTableManager, IServiceProvider serviceProvider,IShardingCoreOptions shardingCoreOptions)
|
||||
IVirtualTableManager virtualTableManager, IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions)
|
||||
{
|
||||
_logger = logger;
|
||||
_shardingDbContextFactory = shardingDbContextFactory;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_shardingCoreOptions = shardingCoreOptions;
|
||||
_shardingConfigOptions = shardingConfigOptions;
|
||||
}
|
||||
|
||||
public void CreateTable<T>(string tail) where T : class, IShardingTable
|
||||
public void CreateTable<TShardingDbContext, T>(string tail) where TShardingDbContext : DbContext, IShardingDbContext where T : class, IShardingTable
|
||||
{
|
||||
CreateTable(typeof(T), tail);
|
||||
CreateTable(typeof(TShardingDbContext),typeof(T), tail);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType"></param>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <param name="tail"></param>
|
||||
/// <exception cref="ShardingCreateException"></exception>
|
||||
public void CreateTable(Type shardingEntityType, string tail)
|
||||
public void CreateTable(Type shardingDbContextType,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 dbContextOptionsProvider = serviceScope.ServiceProvider.GetService<IDbContextOptionsProvider>();
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntityType);
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntityType);
|
||||
var dbContext = (DbContext)serviceScope.ServiceProvider.GetService(shardingDbContextType);
|
||||
var shardingDbContext = (IShardingDbContext)dbContext;
|
||||
var context = shardingDbContext.GetDbContext(true,tail);
|
||||
|
||||
using (var dbContext = _shardingDbContextFactory.Create(new ShardingDbContextOptions(dbContextOptionsProvider.GetDbContextOptions(null), tail)))
|
||||
{
|
||||
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
|
||||
var modelCacheSyncObject = context.GetModelCacheSyncObject();
|
||||
|
||||
lock (modelCacheSyncObject)
|
||||
{
|
||||
dbContext.RemoveDbContextRelationModelSaveOnlyThatIsNamedType(shardingEntityType);
|
||||
var databaseCreator = dbContext.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
|
||||
context.RemoveDbContextRelationModelSaveOnlyThatIsNamedType(shardingEntityType);
|
||||
var databaseCreator = context.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
|
||||
try
|
||||
{
|
||||
databaseCreator.CreateTables();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!_shardingCoreOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||
if (!shardingConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||
{
|
||||
_logger.LogWarning(
|
||||
$"create table error maybe table:[{virtualTable.GetOriginalTableName()}{virtualTable.ShardingConfig.TailPrefix}{tail}]");
|
||||
|
@ -78,7 +92,7 @@ namespace ShardingCore.TableCreator
|
|||
}
|
||||
finally
|
||||
{
|
||||
dbContext.RemoveModelCache();
|
||||
context.RemoveModelCache();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,4 +100,3 @@ namespace ShardingCore.TableCreator
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="Xunit.DependencyInjection" Version="7.1.0" />
|
||||
|
@ -22,5 +23,8 @@
|
|||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -28,5 +28,7 @@ namespace ShardingCore.Test50
|
|||
modelBuilder.ApplyConfiguration(new SysUserModMap());
|
||||
modelBuilder.ApplyConfiguration(new SysUserSalaryMap());
|
||||
}
|
||||
|
||||
public override Type ShardingDbContextType => this.GetType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding;
|
||||
using ShardingCore.SqlServer;
|
||||
using ShardingCore.Test50.Domain.Entities;
|
||||
using ShardingCore.Test50.Shardings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
#if EFCORE5SQLSERVER
|
||||
using ShardingCore.SqlServer;
|
||||
|
@ -30,6 +27,10 @@ namespace ShardingCore.Test50
|
|||
*/
|
||||
public class Startup
|
||||
{
|
||||
public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder =>
|
||||
{
|
||||
builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
|
||||
});
|
||||
// // 自定义 host 构建
|
||||
public void ConfigureHost(IHostBuilder hostBuilder)
|
||||
{
|
||||
|
@ -47,33 +48,18 @@ namespace ShardingCore.Test50
|
|||
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
||||
{
|
||||
|
||||
services.AddShardingSqlServer(o =>
|
||||
{
|
||||
o.EnsureCreatedWithOutShardingTable = false;
|
||||
o.CreateShardingTableOnStart = false;
|
||||
o.UseShardingDbContext<DefaultDbContext>( dbConfig =>
|
||||
{
|
||||
dbConfig.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
dbConfig.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||
});
|
||||
//o.AddDataSourceVirtualRoute<>();
|
||||
|
||||
});
|
||||
//services.AddShardingSqlServer(o =>
|
||||
//{
|
||||
// o.ConnectionString = hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"];
|
||||
// o.AddSharding<SysUserModVirtualTableRoute>();
|
||||
// o.AddSharding<SysUserSalaryVirtualTableRoute>();
|
||||
// o.UseShardingCoreConfig((provider, config) =>
|
||||
// {
|
||||
// config.EnsureCreated = true;
|
||||
// config.CreateShardingTableOnStart = true;
|
||||
// });
|
||||
//});
|
||||
services.AddDbContext<DefaultDbContext>(o =>
|
||||
o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]));
|
||||
services.AddDbContext<ShardingDefaultDbContext>(o=>
|
||||
o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]).UseSharding());
|
||||
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o =>
|
||||
o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]), op =>
|
||||
{
|
||||
|
||||
op.EnsureCreatedWithOutShardingTable = true;
|
||||
op.CreateShardingTableOnStart = true;
|
||||
op.UseShardingDbContextOptions((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger));
|
||||
op.AddShardingTableRoute<SysUserModVirtualTableRoute>();
|
||||
op.AddShardingTableRoute<SysUserSalaryVirtualTableRoute>();
|
||||
});
|
||||
}
|
||||
|
||||
// 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法
|
||||
|
|
Loading…
Reference in New Issue