第一个测试版本
This commit is contained in:
parent
070a952bfd
commit
4accc08567
|
@ -2,7 +2,7 @@
|
||||||
::定义版本
|
::定义版本
|
||||||
set EFCORE2=2.1.0.21
|
set EFCORE2=2.1.0.21
|
||||||
set EFCORE3=3.1.0.21
|
set EFCORE3=3.1.0.21
|
||||||
set EFCORE5=5.1.0.21
|
set EFCORE5=5.2.0.02
|
||||||
|
|
||||||
::删除所有bin与obj下的文件
|
::删除所有bin与obj下的文件
|
||||||
@echo off
|
@echo off
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
@ -6,17 +5,15 @@ using Microsoft.Extensions.DependencyInjection;
|
||||||
using Sample.SqlServer.DbContexts;
|
using Sample.SqlServer.DbContexts;
|
||||||
using Sample.SqlServer.Domain.Entities;
|
using Sample.SqlServer.Domain.Entities;
|
||||||
using ShardingCore;
|
using ShardingCore;
|
||||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
|
||||||
using ShardingCore.Extensions;
|
|
||||||
|
|
||||||
namespace Sample.SqlServer
|
namespace Sample.SqlServer
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Tuesday, 26 January 2021 12:29:04
|
* @Date: Tuesday, 26 January 2021 12:29:04
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public static class DIExtension
|
public static class DIExtension
|
||||||
{
|
{
|
||||||
public static IApplicationBuilder UseShardingCore(this IApplicationBuilder app)
|
public static IApplicationBuilder UseShardingCore(this IApplicationBuilder app)
|
||||||
|
@ -30,24 +27,24 @@ namespace Sample.SqlServer
|
||||||
{
|
{
|
||||||
using (var scope=app.ApplicationServices.CreateScope())
|
using (var scope=app.ApplicationServices.CreateScope())
|
||||||
{
|
{
|
||||||
var virtualDbContext =scope.ServiceProvider.GetService<DefaultTableDbContext>();
|
var virtualDbContext =scope.ServiceProvider.GetService<DefaultShardingDbContext>();
|
||||||
//if (!virtualDbContext.Set<SysUserMod>().ShardingAny())
|
if (!virtualDbContext.Set<SysUserMod>().Any())
|
||||||
//{
|
{
|
||||||
// var ids = Enumerable.Range(1, 1000);
|
var ids = Enumerable.Range(1, 1000);
|
||||||
// var userMods = new List<SysUserMod>();
|
var userMods = new List<SysUserMod>();
|
||||||
// foreach (var id in ids)
|
foreach (var id in ids)
|
||||||
// {
|
{
|
||||||
// userMods.Add(new SysUserMod()
|
userMods.Add(new SysUserMod()
|
||||||
// {
|
{
|
||||||
// Id = id.ToString(),
|
Id = id.ToString(),
|
||||||
// Age = id,
|
Age = id,
|
||||||
// Name = $"name_{id}",
|
Name = $"name_{id}",
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// virtualDbContext.AddRange(userMods);
|
virtualDbContext.AddRange(userMods);
|
||||||
// virtualDbContext.SaveChanges();
|
virtualDbContext.SaveChanges();
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,5 +21,6 @@ namespace Sample.SqlServer.DbContexts
|
||||||
modelBuilder.ApplyConfiguration(new SysTestMap());
|
modelBuilder.ApplyConfiguration(new SysTestMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Type ShardingDbContextType => this.GetType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,12 @@
|
||||||
<LangVersion>9.0</LangVersion>
|
<LangVersion>9.0</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</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.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Data.SqlClient;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Sample.SqlServer.DbContexts;
|
using Sample.SqlServer.DbContexts;
|
||||||
using Sample.SqlServer.Shardings;
|
using Sample.SqlServer.Shardings;
|
||||||
using ShardingCore;
|
using ShardingCore;
|
||||||
using ShardingCore.EFCores;
|
|
||||||
using ShardingCore.SqlServer;
|
|
||||||
|
|
||||||
namespace Sample.SqlServer
|
namespace Sample.SqlServer
|
||||||
{
|
{
|
||||||
|
@ -30,31 +21,17 @@ namespace Sample.SqlServer
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddControllers();
|
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.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)
|
op.EnsureCreatedWithOutShardingTable = true;
|
||||||
.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll)
|
op.CreateShardingTableOnStart = true;
|
||||||
.ReplaceService<IModelCacheKeyFactory, ShardingModelCacheKeyFactory>()
|
op.UseShardingDbContextOptions((connection, builder) => builder.UseSqlServer(connection).UseLoggerFactory(efLogger));
|
||||||
.ReplaceService<IModelCustomizer, ShardingModelCustomizer>().Options;
|
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.
|
// 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.UseRouting();
|
||||||
|
|
||||||
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
|
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 System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
{
|
{
|
||||||
|
@ -10,6 +13,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
*/
|
*/
|
||||||
public interface IRouteRuleEngine
|
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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
{
|
{
|
||||||
|
@ -13,7 +16,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
{
|
{
|
||||||
IRouteRuleEngine CreateEngine();
|
IRouteRuleEngine CreateEngine();
|
||||||
RouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
|
RouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
|
||||||
IEnumerable<RouteResult> Route<T>(IQueryable<T> queryable);
|
IEnumerable<RouteResult> Route<T,TShardingDbContext>(IQueryable<T> queryable) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||||
IEnumerable<RouteResult> Route<T>(RouteRuleContext<T> ruleContext);
|
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.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core.PhysicTables;
|
using ShardingCore.Core.PhysicTables;
|
||||||
using ShardingCore.Core.VirtualTables;
|
using ShardingCore.Core.VirtualTables;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
#if !EFCORE5
|
#if !EFCORE5
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,30 +28,9 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
_virtualTableManager = virtualTableManager;
|
_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>>();
|
return Route(typeof(TShardingDbContext), routeRuleContext);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
////先添加手动路由到当前上下文,之后将不再手动路由里面的自动路由添加到当前上下文
|
////先添加手动路由到当前上下文,之后将不再手动路由里面的自动路由添加到当前上下文
|
||||||
//foreach (var kv in routeRuleContext.ManualTails)
|
//foreach (var kv in routeRuleContext.ManualTails)
|
||||||
//{
|
//{
|
||||||
|
@ -105,8 +88,34 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
return routeMaps.Select(o => o.Value).Cartesian().Select(o=>new RouteResult(o));
|
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,21 +1,24 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core.VirtualTables;
|
using ShardingCore.Core.VirtualTables;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Thursday, 28 January 2021 13:31:06
|
* @Date: Thursday, 28 January 2021 13:31:06
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public class RoutingRuleEngineFactory : IRoutingRuleEngineFactory
|
public class RoutingRuleEngineFactory : IRoutingRuleEngineFactory
|
||||||
{
|
{
|
||||||
private readonly IRouteRuleEngine _routeRuleEngine;
|
private readonly IRouteRuleEngine _routeRuleEngine;
|
||||||
private readonly IVirtualTableManager _virtualTableManager;
|
private readonly IVirtualTableManager _virtualTableManager;
|
||||||
|
|
||||||
public RoutingRuleEngineFactory(IRouteRuleEngine routeRuleEngine,IVirtualTableManager virtualTableManager)
|
public RoutingRuleEngineFactory(IRouteRuleEngine routeRuleEngine, IVirtualTableManager virtualTableManager)
|
||||||
{
|
{
|
||||||
_routeRuleEngine = routeRuleEngine;
|
_routeRuleEngine = routeRuleEngine;
|
||||||
_virtualTableManager = virtualTableManager;
|
_virtualTableManager = virtualTableManager;
|
||||||
|
@ -31,17 +34,30 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||||
return new RouteRuleContext<T>(queryable, _virtualTableManager);
|
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 engine = CreateEngine();
|
||||||
var ruleContext = CreateContext<T>(queryable);
|
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();
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core.PhysicTables;
|
using ShardingCore.Core.PhysicTables;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.VirtualTables
|
namespace ShardingCore.Core.VirtualTables
|
||||||
{
|
{
|
||||||
|
@ -18,58 +20,70 @@ namespace ShardingCore.Core.VirtualTables
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加虚拟表应用启动时 add virtual table when app start
|
/// 添加虚拟表应用启动时 add virtual table when app start
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <param name="virtualTable">虚拟表</param>
|
/// <param name="virtualTable">虚拟表</param>
|
||||||
void AddVirtualTable(IVirtualTable virtualTable);
|
void AddVirtualTable(Type shardingDbContextType,IVirtualTable virtualTable);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取虚拟表 get virtual table by sharding entity type
|
/// 获取虚拟表 get virtual table by sharding entity type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <param name="shardingEntityType"></param>
|
/// <param name="shardingEntityType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IVirtualTable GetVirtualTable(Type shardingEntityType);
|
IVirtualTable GetVirtualTable(Type shardingDbContextType, Type shardingEntityType);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取虚拟表 get virtual table by sharding entity type
|
/// 获取虚拟表 get virtual table by sharding entity type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IVirtualTable<T> GetVirtualTable<T>() where T : class, IShardingTable;
|
IVirtualTable<T> GetVirtualTable<TDbContext,T>() where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取虚拟表 get virtual table by original table name
|
/// 获取虚拟表 get virtual table by original table name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <param name="originalTableName"></param>
|
/// <param name="originalTableName"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IVirtualTable GetVirtualTable(string originalTableName);
|
IVirtualTable GetVirtualTable(Type shardingDbContextType, string originalTableName);
|
||||||
|
IVirtualTable GetVirtualTable<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 尝试获取虚拟表没有返回null
|
/// 尝试获取虚拟表没有返回null
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <param name="originalTableName"></param>
|
/// <param name="originalTableName"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IVirtualTable TryGetVirtualTable(string originalTableName);
|
IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string originalTableName);
|
||||||
|
IVirtualTable TryGetVirtualTablee<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取所有的虚拟表 get all virtual table
|
/// 获取所有的虚拟表 get all virtual table
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<IVirtualTable> GetAllVirtualTables();
|
List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType);
|
||||||
|
List<IVirtualTable> GetAllVirtualTables<TDbContext>() where TDbContext : DbContext, IShardingDbContext;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 添加物理表 add physic table
|
/// 添加物理表 add physic table
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <param name="virtualTable"></param>
|
/// <param name="virtualTable"></param>
|
||||||
/// <param name="physicTable"></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>
|
/// <summary>
|
||||||
/// 添加物理表 add physic table
|
/// 添加物理表 add physic table
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||||
/// <param name="shardingEntityType"></param>
|
/// <param name="shardingEntityType"></param>
|
||||||
/// <param name="physicTable"></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>
|
///// <summary>
|
||||||
///// 添加物理表 add physic table
|
///// 添加物理表 add physic table
|
||||||
|
|
|
@ -2,25 +2,29 @@ using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core.PhysicTables;
|
using ShardingCore.Core.PhysicTables;
|
||||||
using ShardingCore.Exceptions;
|
using ShardingCore.Exceptions;
|
||||||
|
using ShardingCore.Extensions;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Core.VirtualTables
|
namespace ShardingCore.Core.VirtualTables
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Friday, 18 December 2020 14:52:42
|
* @Date: Friday, 18 December 2020 14:52:42
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 同一个数据库下的虚拟表管理者
|
/// 同一个数据库下的虚拟表管理者
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OneDbVirtualTableManager : IVirtualTableManager
|
public class OneDbVirtualTableManager : IVirtualTableManager
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly ConcurrentDictionary<Type, IVirtualTable> _shardingVirtualTables = new ConcurrentDictionary<Type, IVirtualTable>();
|
//{sharidngDbContextType:{entityType,virtualTableType}}
|
||||||
private readonly ConcurrentDictionary<string, IVirtualTable> _shardingOriginalTaleVirtualTales = new ConcurrentDictionary<string, IVirtualTable>();
|
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)
|
public OneDbVirtualTableManager(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_serviceProvider = 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))
|
if (!shardingDbContextType.IsShardingDbContext())
|
||||||
|
throw new ShardingCoreException(
|
||||||
|
$"{shardingDbContextType.FullName} must impl {nameof(IShardingDbContext)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckShardingTableEntityType(Type shardingEntityType)
|
||||||
|
{
|
||||||
|
if (!shardingEntityType.IsShardingTable())
|
||||||
|
throw new ShardingCoreException(
|
||||||
|
$"{shardingEntityType.FullName} must impl {nameof(IShardingTable)}");
|
||||||
|
}
|
||||||
|
private string CreateShardingEntityTypeKey(Type shardingDbContextType, Type entityType)
|
||||||
|
{
|
||||||
|
return $"{shardingDbContextType.FullName}{entityType.FullName}";
|
||||||
|
}
|
||||||
|
private string CreateShardingTableNameKey(Type shardingDbContextType, string originalTableName)
|
||||||
|
{
|
||||||
|
return $"{shardingDbContextType.FullName}{originalTableName}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVirtualTable(Type shardingDbContextType, IVirtualTable virtualTable)
|
||||||
|
{
|
||||||
|
CheckShardingDbContextType(shardingDbContextType);
|
||||||
|
|
||||||
|
var innerShardingVirtualTables = _shardingVirtualTables.GetOrAdd(shardingDbContextType,
|
||||||
|
key => new ConcurrentDictionary<Type, IVirtualTable>());
|
||||||
|
|
||||||
|
if (!innerShardingVirtualTables.ContainsKey(virtualTable.EntityType))
|
||||||
{
|
{
|
||||||
_shardingVirtualTables.TryAdd(virtualTable.EntityType, virtualTable);
|
innerShardingVirtualTables.TryAdd(virtualTable.EntityType, virtualTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_shardingOriginalTaleVirtualTales.ContainsKey(virtualTable.GetOriginalTableName()))
|
var innerShardingOriginalTableVirtualTables = _shardingOriginalTaleVirtualTales.GetOrAdd(shardingDbContextType,type=>new ConcurrentDictionary<string, IVirtualTable>());
|
||||||
|
|
||||||
|
if (!innerShardingOriginalTableVirtualTables.ContainsKey(virtualTable.GetOriginalTableName()))
|
||||||
{
|
{
|
||||||
_shardingOriginalTaleVirtualTales.TryAdd(virtualTable.GetOriginalTableName(), virtualTable);
|
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);
|
throw new ShardingVirtualTableNotFoundException(shardingEntityType.FullName);
|
||||||
return virtualTable;
|
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);
|
throw new ShardingVirtualTableNotFoundException(originalTableName);
|
||||||
return virtualTable;
|
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 null;
|
||||||
return virtualTable;
|
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);
|
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>
|
///// <summary>
|
||||||
///// 是否是分表字段
|
///// 是否是分表字段
|
||||||
|
@ -103,7 +180,7 @@ namespace ShardingCore.Core.VirtualTables
|
||||||
///// <returns></returns>
|
///// <returns></returns>
|
||||||
//public bool IsShardingKey(Type shardingEntityType, string shardingField)
|
//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;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Internal;
|
||||||
|
using Microsoft.EntityFrameworkCore.Query.Internal;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ShardingCore.Core.Internal.StreamMerge;
|
|
||||||
using ShardingCore.Core.ShardingAccessors;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
using ShardingCore.Core.VirtualTables;
|
using ShardingCore.Core.VirtualTables;
|
||||||
using ShardingCore.DbContexts;
|
using ShardingCore.DbContexts;
|
||||||
using ShardingCore.DbContexts.Abstractions;
|
using ShardingCore.EFCores;
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
using ShardingCore.Helpers;
|
||||||
using ShardingCore.Sharding;
|
using ShardingCore.Sharding;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
using ShardingCore.Sharding.Enumerators;
|
|
||||||
using ShardingCore.TableCreator;
|
using ShardingCore.TableCreator;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace ShardingCore
|
namespace ShardingCore
|
||||||
{
|
{
|
||||||
|
@ -24,9 +24,48 @@ namespace ShardingCore
|
||||||
public static class DIExtension
|
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<IStreamMergeContextFactory, StreamMergeContextFactory>();
|
||||||
|
|
||||||
services.AddSingleton<IShardingDbContextFactory, ShardingDbContextFactory>();
|
services.AddSingleton<IShardingDbContextFactory, ShardingDbContextFactory>();
|
||||||
|
@ -38,33 +77,20 @@ namespace ShardingCore
|
||||||
//分表引擎
|
//分表引擎
|
||||||
services.AddSingleton<IRouteRuleEngine, QueryRouteRuleEngines>();
|
services.AddSingleton<IRouteRuleEngine, QueryRouteRuleEngines>();
|
||||||
//services.AddSingleton(typeof(IVirtualTable<>), typeof(OneDbVirtualTable<>));
|
//services.AddSingleton(typeof(IVirtualTable<>), typeof(OneDbVirtualTable<>));
|
||||||
services.AddSingleton<IShardingAccessor, ShardingAccessor>();
|
//services.AddSingleton<IShardingAccessor, ShardingAccessor>();
|
||||||
services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
|
//services.AddSingleton<IShardingScopeFactory, ShardingScopeFactory>();
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static DbContextOptionsBuilder UseSharding(this DbContextOptionsBuilder optionsBuilder)
|
||||||
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
|
|
||||||
{
|
{
|
||||||
if (configure == null)
|
return optionsBuilder.ReplaceService<IDbSetSource, ShardingDbSetSource>()
|
||||||
throw new ArgumentNullException($"AddScfSqlServerProvider 参数不能为空:{nameof(configure)}");
|
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>();
|
||||||
var shardingConfig = new ShardingConfig<TActualDbContext>();
|
}
|
||||||
configure?.Invoke(shardingConfig);
|
internal static DbContextOptionsBuilder UseInnerDbContextSharding<TShardingDbContext>(this DbContextOptionsBuilder optionsBuilder) where TShardingDbContext:DbContext,IShardingDbContext
|
||||||
services.AddSingleton(shardingConfig);
|
{
|
||||||
|
return optionsBuilder.ReplaceService<IModelCacheKeyFactory, ShardingModelCacheKeyFactory>()
|
||||||
services.AddDbContext<TShardingDbContext>(optionsAction, contextLifetime, optionsLifetime);
|
.ReplaceService<IModelCustomizer, ShardingModelCustomizer<TShardingDbContext>>();
|
||||||
services.AddShardingCore();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
services.AddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
|
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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 Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.DbContexts
|
namespace ShardingCore.DbContexts
|
||||||
{
|
{
|
||||||
|
@ -14,7 +15,8 @@ namespace ShardingCore.DbContexts
|
||||||
*/
|
*/
|
||||||
public interface IShardingDbContextFactory
|
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);
|
//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,64 +1,54 @@
|
||||||
using System;
|
|
||||||
using System.Data.Common;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using ShardingCore.Core.VirtualTables;
|
|
||||||
using ShardingCore.DbContexts.Abstractions;
|
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace ShardingCore.DbContexts
|
namespace ShardingCore.DbContexts
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Thursday, 24 December 2020 08:22:48
|
* @Date: Thursday, 24 December 2020 08:22:48
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public class ShardingDbContextFactory:IShardingDbContextFactory
|
public class ShardingDbContextFactory:IShardingDbContextFactory
|
||||||
{
|
{
|
||||||
private readonly IShardingCoreOptions _shardingCoreOptions;
|
private readonly IEnumerable<IShardingDbContextCreatorConfig> _shardingDbContextCreatorConfigs;
|
||||||
private readonly IDbContextCreateFilterManager _dbContextCreateFilterManager;
|
|
||||||
private readonly IDbContextOptionsProvider _dbContextOptionsProvider;
|
|
||||||
|
|
||||||
public ShardingDbContextFactory(IShardingCoreOptions shardingCoreOptions, IDbContextCreateFilterManager dbContextCreateFilterManager,IDbContextOptionsProvider dbContextOptionsProvider)
|
public ShardingDbContextFactory(IEnumerable<IShardingDbContextCreatorConfig> shardingDbContextCreatorConfigs)
|
||||||
{
|
{
|
||||||
_shardingCoreOptions = shardingCoreOptions;
|
_shardingDbContextCreatorConfigs = shardingDbContextCreatorConfigs;
|
||||||
_dbContextCreateFilterManager = dbContextCreateFilterManager;
|
|
||||||
_dbContextOptionsProvider = dbContextOptionsProvider;
|
|
||||||
}
|
}
|
||||||
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 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)
|
if (!string.IsNullOrWhiteSpace(tail) && dbContext is IShardingTableDbContext shardingTableDbContext)
|
||||||
{
|
{
|
||||||
shardingTableDbContext.SetShardingTableDbContextTail(tail);
|
shardingTableDbContext.SetShardingTableDbContextTail(tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
var filters = _dbContextCreateFilterManager.GetFilters();
|
|
||||||
if (filters.Any())
|
|
||||||
{
|
|
||||||
foreach (var dbContextCreateFilter in filters)
|
|
||||||
{
|
|
||||||
dbContextCreateFilter.CreateAfter(dbContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var dbContextModel = dbContext.Model;
|
var dbContextModel = dbContext.Model;
|
||||||
return dbContext;
|
return dbContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public DbContext Create(DbConnection dbConnection,string tail)
|
public DbContext Create<TShardingDbContext>(ShardingDbContextOptions shardingDbContextOptions) where TShardingDbContext : DbContext, IShardingDbContext
|
||||||
//{
|
{
|
||||||
// var shardingDbContextOptions =
|
return Create(typeof(TShardingDbContext), shardingDbContextOptions);
|
||||||
// new ShardingDbContextOptions(_dbContextOptionsProvider.GetDbContextOptions(dbConnection), tail);
|
}
|
||||||
// return Create(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
|
* @Ver: 1.0
|
||||||
* @Email: 326308290@qq.com
|
* @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)
|
public ShardingModelCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -36,7 +37,7 @@ namespace ShardingCore.EFCores
|
||||||
if (!string.IsNullOrWhiteSpace(tail))
|
if (!string.IsNullOrWhiteSpace(tail))
|
||||||
{
|
{
|
||||||
var virtualTableManager = ShardingContainer.Services.GetService<IVirtualTableManager>();
|
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));
|
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
|
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>
|
/// <summary>
|
||||||
/// IShardingTableDbContext
|
/// IShardingTableDbContext
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -41,6 +67,8 @@ namespace ShardingCore.Extensions
|
||||||
{
|
{
|
||||||
if (dbContextType == null)
|
if (dbContextType == null)
|
||||||
throw new ArgumentNullException(nameof(dbContextType));
|
throw new ArgumentNullException(nameof(dbContextType));
|
||||||
|
if (!typeof(DbContext).IsAssignableFrom(dbContextType))
|
||||||
|
return false;
|
||||||
return typeof(IShardingTableDbContext).IsAssignableFrom(dbContextType);
|
return typeof(IShardingTableDbContext).IsAssignableFrom(dbContextType);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -64,7 +92,7 @@ namespace ShardingCore.Extensions
|
||||||
{
|
{
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
throw new ArgumentNullException(nameof(entity));
|
throw new ArgumentNullException(nameof(entity));
|
||||||
return typeof(IShardingTable).IsAssignableFrom(entity.GetType());
|
return entity is IShardingTable;
|
||||||
}
|
}
|
||||||
// /// <summary>
|
// /// <summary>
|
||||||
// /// 虚拟表转换成对应的db配置
|
// /// 虚拟表转换成对应的db配置
|
||||||
|
@ -73,7 +101,7 @@ namespace ShardingCore.Extensions
|
||||||
// /// <returns></returns>
|
// /// <returns></returns>
|
||||||
// public static List<VirtualTableDbContextConfig> GetVirtualTableDbContextConfigs(this List<IVirtualTable> virtualTables)
|
// 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>
|
/// <summary>
|
||||||
/// 是否是集合contains方法
|
/// 是否是集合contains方法
|
||||||
|
|
|
@ -26,9 +26,7 @@ namespace ShardingCore.Extensions
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string GetShardingTableDbContextTail(this IShardingTableDbContext dbContext)
|
public static string GetShardingTableDbContextTail(this IShardingTableDbContext dbContext)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(dbContext.ModelChangeKey))
|
return dbContext.ModelChangeKey?.Replace(ShardingTableDbContextFormat, string.Empty)??string.Empty;
|
||||||
throw new ShardingCoreException($"cant found ModelChangeKey in {dbContext.GetType().FullName}");
|
|
||||||
return dbContext.ModelChangeKey.Replace(ShardingTableDbContextFormat, string.Empty);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -6,23 +6,26 @@ using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
using ShardingCore.Exceptions;
|
using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.Helpers
|
namespace ShardingCore.Helpers
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Friday, 22 January 2021 13:32:08
|
* @Date: Friday, 22 January 2021 13:32:08
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public class ShardingCoreHelper
|
public class ShardingCoreHelper
|
||||||
{
|
{
|
||||||
private ShardingCoreHelper(){}
|
private ShardingCoreHelper() { }
|
||||||
public static int GetStringHashCode(string value)
|
public static int GetStringHashCode(string value)
|
||||||
{
|
{
|
||||||
int h = 0; // 默认值是0
|
int h = 0; // 默认值是0
|
||||||
if (value.Length > 0) {
|
if (value.Length > 0)
|
||||||
for (int i = 0; i < value.Length; i++) {
|
{
|
||||||
|
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]
|
h = 31 * h + value[i]; // val[0]*31^(n-1) + val[1]*31^(n-2) + ... + val[n-1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +39,7 @@ namespace ShardingCore.Helpers
|
||||||
}
|
}
|
||||||
public static long ConvertDateTimeToLong(DateTime time)
|
public static long ConvertDateTimeToLong(DateTime time)
|
||||||
{
|
{
|
||||||
return (long) (time.AddHours(-8) - UtcStartTime).TotalMilliseconds;
|
return (long)(time.AddHours(-8) - UtcStartTime).TotalMilliseconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -61,7 +64,7 @@ namespace ShardingCore.Helpers
|
||||||
public static DateTime GetCurrentMonday(DateTime time)
|
public static DateTime GetCurrentMonday(DateTime time)
|
||||||
{
|
{
|
||||||
DateTime dateTime1 = new DateTime(time.Year, time.Month, time.Day);
|
DateTime dateTime1 = new DateTime(time.Year, time.Month, time.Day);
|
||||||
int num = (int) (time.DayOfWeek - 1);
|
int num = (int)(time.DayOfWeek - 1);
|
||||||
if (num == -1)
|
if (num == -1)
|
||||||
num = 6;
|
num = 6;
|
||||||
return dateTime1.AddDays(-num);
|
return dateTime1.AddDays(-num);
|
||||||
|
@ -88,7 +91,7 @@ namespace ShardingCore.Helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
var paramType = declaredConstructors[0].GetParameters()[0].ParameterType;
|
var paramType = declaredConstructors[0].GetParameters()[0].ParameterType;
|
||||||
if (paramType != typeof(ShardingDbContextOptions) && paramType != typeof(DbContextOptions) && paramType!= typeof(DbContextOptions<TContext>))
|
if (paramType != typeof(ShardingDbContextOptions) && paramType != typeof(DbContextOptions) && paramType != typeof(DbContextOptions<TContext>))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"dbcontext : {contextType} declared constructor parameters should use {typeof(ShardingDbContextOptions)} or {typeof(DbContextOptions)} or {typeof(DbContextOptions<TContext>)} ");
|
throw new ArgumentException($"dbcontext : {contextType} declared constructor parameters should use {typeof(ShardingDbContextOptions)} or {typeof(DbContextOptions)} or {typeof(DbContextOptions<TContext>)} ");
|
||||||
}
|
}
|
||||||
|
@ -103,8 +106,7 @@ namespace ShardingCore.Helpers
|
||||||
//}
|
//}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public static Func<ShardingDbContextOptions, DbContext> CreateActivator<TContext>() where TContext : DbContext, IShardingTableDbContext
|
||||||
public static Func<ShardingDbContextOptions, DbContext> CreateActivator<TContext>() where TContext : DbContext
|
|
||||||
{
|
{
|
||||||
var constructors
|
var constructors
|
||||||
= typeof(TContext).GetTypeInfo().DeclaredConstructors
|
= typeof(TContext).GetTypeInfo().DeclaredConstructors
|
||||||
|
@ -118,7 +120,7 @@ namespace ShardingCore.Helpers
|
||||||
|
|
||||||
if (parameterType == typeof(ShardingDbContextOptions))
|
if (parameterType == typeof(ShardingDbContextOptions))
|
||||||
{
|
{
|
||||||
return CreateShardingDbContextOptionsActivator<TContext>(constructors[0],parameterType);
|
return CreateShardingDbContextOptionsActivator<TContext>(constructors[0], parameterType);
|
||||||
}
|
}
|
||||||
else if (typeof(DbContextOptions).IsAssignableFrom(parameterType))
|
else if (typeof(DbContextOptions).IsAssignableFrom(parameterType))
|
||||||
{
|
{
|
||||||
|
@ -147,7 +149,7 @@ namespace ShardingCore.Helpers
|
||||||
/// <param name="constructor"></param>
|
/// <param name="constructor"></param>
|
||||||
/// <param name="paramType"></param>
|
/// <param name="paramType"></param>
|
||||||
/// <returns></returns>
|
/// <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 po = Expression.Parameter(paramType, "o");
|
||||||
var newExpression = Expression.New(constructor, po);
|
var newExpression = Expression.New(constructor, po);
|
||||||
|
@ -166,7 +168,7 @@ namespace ShardingCore.Helpers
|
||||||
/// <param name="constructor"></param>
|
/// <param name="constructor"></param>
|
||||||
/// <param name="paramType"></param>
|
/// <param name="paramType"></param>
|
||||||
/// <returns></returns>
|
/// <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");
|
var parameterExpression = Expression.Parameter(typeof(ShardingDbContextOptions), "o");
|
||||||
//o.DbContextOptions
|
//o.DbContextOptions
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace ShardingCore
|
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;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -30,13 +31,13 @@ namespace ShardingCore.Sharding
|
||||||
/// 分表分库的dbcontext
|
/// 分表分库的dbcontext
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <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 string EMPTY_SHARDING_TAIL_ID = Guid.NewGuid().ToString("n");
|
||||||
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
||||||
private readonly IVirtualTableManager _virtualTableManager;
|
private readonly IVirtualTableManager _virtualTableManager;
|
||||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||||
private readonly ShardingConfig<T> _shardingConfig;
|
private readonly IShardingDbContextOptionsBuilderConfig _shardingDbContextOptionsBuilderConfig;
|
||||||
private DbContextOptions<T> _dbContextOptions;
|
private DbContextOptions<T> _dbContextOptions;
|
||||||
|
|
||||||
private readonly object CREATELOCK = new object();
|
private readonly object CREATELOCK = new object();
|
||||||
|
@ -45,10 +46,13 @@ namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory>();
|
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory>();
|
||||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager>();
|
_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);
|
public Type ActualDbContextType => typeof(T);
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,8 +68,8 @@ namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||||
var dbConnection = Database.GetDbConnection();
|
var dbConnection = Database.GetDbConnection();
|
||||||
dbConnection.Open();
|
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
||||||
return _shardingConfig.ShardingDbContextOptionsCreator(dbConnection, dbContextOptionBuilder);
|
return dbContextOptionBuilder.Options;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ShardingDbContextOptions CreateSameShardingDbContextOptions(string tail)
|
private ShardingDbContextOptions CreateSameShardingDbContextOptions(string tail)
|
||||||
|
@ -87,7 +91,7 @@ namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
if (!_dbContextCaches.TryGetValue(tail, out var dbContext))
|
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);
|
_dbContextCaches.TryAdd(tail, dbContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,13 +105,25 @@ namespace ShardingCore.Sharding
|
||||||
var tail = EMPTY_SHARDING_TAIL_ID;
|
var tail = EMPTY_SHARDING_TAIL_ID;
|
||||||
if (entity.IsShardingTable())
|
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;
|
tail = physicTable.Tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetDbContext(true, 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)
|
public override EntityEntry Add(object entity)
|
||||||
{
|
{
|
||||||
return CreateGenericDbContext(entity).Add(entity);
|
return CreateGenericDbContext(entity).Add(entity);
|
||||||
|
@ -380,12 +396,14 @@ namespace ShardingCore.Sharding
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (!isBeginTransaction)
|
if (!isBeginTransaction)
|
||||||
Database.CurrentTransaction?.Dispose();
|
|
||||||
|
|
||||||
foreach (var dbContextCache in _dbContextCaches)
|
|
||||||
{
|
{
|
||||||
dbContextCache.Value.Database.UseTransaction(null);
|
Database.CurrentTransaction?.Dispose();
|
||||||
|
foreach (var dbContextCache in _dbContextCaches)
|
||||||
|
{
|
||||||
|
dbContextCache.Value.Database.UseTransaction(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -415,11 +433,12 @@ namespace ShardingCore.Sharding
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (!isBeginTransaction)
|
if (!isBeginTransaction)
|
||||||
Database.CurrentTransaction?.Dispose();
|
|
||||||
|
|
||||||
foreach (var dbContextCache in _dbContextCaches)
|
|
||||||
{
|
{
|
||||||
dbContextCache.Value.Database.UseTransaction(null);
|
Database.CurrentTransaction?.Dispose();
|
||||||
|
foreach (var dbContextCache in _dbContextCaches)
|
||||||
|
{
|
||||||
|
dbContextCache.Value.Database.UseTransaction(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
@ -451,12 +470,14 @@ namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
if (!isBeginTransaction) { }
|
if (!isBeginTransaction) { }
|
||||||
if (Database.CurrentTransaction != null)
|
if (Database.CurrentTransaction != null)
|
||||||
await Database.CurrentTransaction.DisposeAsync();
|
|
||||||
|
|
||||||
foreach (var dbContextCache in _dbContextCaches)
|
|
||||||
{
|
{
|
||||||
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
await Database.CurrentTransaction.DisposeAsync();
|
||||||
|
foreach (var dbContextCache in _dbContextCaches)
|
||||||
|
{
|
||||||
|
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -487,12 +508,15 @@ namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
if (!isBeginTransaction)
|
if (!isBeginTransaction)
|
||||||
if (Database.CurrentTransaction != null)
|
if (Database.CurrentTransaction != null)
|
||||||
|
{
|
||||||
await Database.CurrentTransaction.DisposeAsync();
|
await Database.CurrentTransaction.DisposeAsync();
|
||||||
|
|
||||||
foreach (var dbContextCache in _dbContextCaches)
|
foreach (var dbContextCache in _dbContextCaches)
|
||||||
{
|
{
|
||||||
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
await dbContextCache.Value.Database.UseTransactionAsync(null, cancellationToken: cancellationToken);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,14 +13,15 @@ namespace ShardingCore.Sharding.Abstractions
|
||||||
*/
|
*/
|
||||||
public interface IShardingDbContext
|
public interface IShardingDbContext
|
||||||
{
|
{
|
||||||
|
Type ShardingDbContextType { get; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 真实的DbContext 类型
|
/// 真实的DbContext 类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Type ActualDbContextType { get;}
|
Type ActualDbContextType { get;}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建DbContext
|
/// 创建DbContext
|
||||||
/// </summary>
|
/// </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>
|
/// <param name="tail"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
DbContext GetDbContext(bool track,string tail);
|
DbContext GetDbContext(bool track,string tail);
|
||||||
|
@ -33,5 +34,12 @@ namespace ShardingCore.Sharding.Abstractions
|
||||||
DbContext CreateGenericDbContext<T>(T entity) where T : class;
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace ShardingCore.Sharding.Abstractions
|
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,27 +1,24 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core.Internal.StreamMerge.ReWrite;
|
using ShardingCore.Core.Internal.StreamMerge.ReWrite;
|
||||||
using ShardingCore.Core.Internal.Visitors;
|
using ShardingCore.Core.Internal.Visitors;
|
||||||
using ShardingCore.Core.Internal.Visitors.GroupBys;
|
using ShardingCore.Core.Internal.Visitors.GroupBys;
|
||||||
using ShardingCore.Core.Internal.Visitors.Selects;
|
using ShardingCore.Core.Internal.Visitors.Selects;
|
||||||
using ShardingCore.Core.ShardingAccessors;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
using ShardingCore.DbContexts;
|
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
|
||||||
namespace ShardingCore.Sharding
|
namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Monday, 25 January 2021 11:38:27
|
* @Date: Monday, 25 January 2021 11:38:27
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public class StreamMergeContext<T>
|
public class StreamMergeContext<T>
|
||||||
{
|
{
|
||||||
private readonly IShardingParallelDbContextFactory _shardingParallelDbContextFactory;
|
|
||||||
//private readonly IShardingScopeFactory _shardingScopeFactory;
|
//private readonly IShardingScopeFactory _shardingScopeFactory;
|
||||||
private readonly IQueryable<T> _source;
|
private readonly IQueryable<T> _source;
|
||||||
private readonly IShardingDbContext _shardingDbContext;
|
private readonly IShardingDbContext _shardingDbContext;
|
||||||
|
@ -37,10 +34,8 @@ namespace ShardingCore.Sharding
|
||||||
public SelectContext SelectContext { get;}
|
public SelectContext SelectContext { get;}
|
||||||
public GroupByContext GroupByContext { get; }
|
public GroupByContext GroupByContext { get; }
|
||||||
|
|
||||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory,
|
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory)
|
||||||
IShardingParallelDbContextFactory shardingParallelDbContextFactory,IShardingScopeFactory shardingScopeFactory)
|
|
||||||
{
|
{
|
||||||
_shardingParallelDbContextFactory = shardingParallelDbContextFactory;
|
|
||||||
//_shardingScopeFactory = shardingScopeFactory;
|
//_shardingScopeFactory = shardingScopeFactory;
|
||||||
_source = source;
|
_source = source;
|
||||||
_shardingDbContext = shardingDbContext;
|
_shardingDbContext = shardingDbContext;
|
||||||
|
@ -69,13 +64,17 @@ namespace ShardingCore.Sharding
|
||||||
// _reWriteSource = reWriteResult.ReWriteQueryable;
|
// _reWriteSource = reWriteResult.ReWriteQueryable;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
public bool TryOpen()
|
||||||
|
{
|
||||||
|
return _shardingDbContext.TryOpen();
|
||||||
|
}
|
||||||
public DbContext CreateDbContext(string tail)
|
public DbContext CreateDbContext(string tail)
|
||||||
{
|
{
|
||||||
return _shardingDbContext.GetDbContext(true,tail);
|
return _shardingDbContext.GetDbContext(true,tail);
|
||||||
}
|
}
|
||||||
public IEnumerable<RouteResult> GetRouteResults()
|
public IEnumerable<RouteResult> GetRouteResults()
|
||||||
{
|
{
|
||||||
return _tableRoutingRuleEngineFactory.Route(_source);
|
return _tableRoutingRuleEngineFactory.Route(_shardingDbContext.GetType(),_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
//public ShardingScope CreateScope()
|
//public ShardingScope CreateScope()
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System.Linq;
|
|
||||||
using ShardingCore.Core.ShardingAccessors;
|
|
||||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||||
using ShardingCore.DbContexts;
|
|
||||||
using ShardingCore.Sharding.Abstractions;
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace ShardingCore.Sharding
|
namespace ShardingCore.Sharding
|
||||||
{
|
{
|
||||||
|
@ -14,21 +12,16 @@ namespace ShardingCore.Sharding
|
||||||
*/
|
*/
|
||||||
public class StreamMergeContextFactory:IStreamMergeContextFactory
|
public class StreamMergeContextFactory:IStreamMergeContextFactory
|
||||||
{
|
{
|
||||||
private readonly IShardingParallelDbContextFactory _shardingParallelDbContextFactory;
|
|
||||||
private readonly IShardingScopeFactory _shardingScopeFactory;
|
|
||||||
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
||||||
|
|
||||||
public StreamMergeContextFactory(IShardingParallelDbContextFactory shardingParallelDbContextFactory,
|
public StreamMergeContextFactory(
|
||||||
IShardingScopeFactory shardingScopeFactory,
|
|
||||||
IRoutingRuleEngineFactory routingRuleEngineFactory)
|
IRoutingRuleEngineFactory routingRuleEngineFactory)
|
||||||
{
|
{
|
||||||
_shardingParallelDbContextFactory = shardingParallelDbContextFactory;
|
|
||||||
_shardingScopeFactory = shardingScopeFactory;
|
|
||||||
_routingRuleEngineFactory = routingRuleEngineFactory;
|
_routingRuleEngineFactory = routingRuleEngineFactory;
|
||||||
}
|
}
|
||||||
public StreamMergeContext<T> Create<T>(IQueryable<T> queryable,IShardingDbContext shardingDbContext)
|
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 = ShardingContainer.GetService<IStreamMergeContextFactory>().Create(_queryable, shardingDbContext);
|
||||||
|
_mergeContext.TryOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IQueryable<TEntity> ProcessSecondExpression(IQueryable<TEntity> queryable, Expression secondExpression);
|
protected abstract IQueryable<TEntity> ProcessSecondExpression(IQueryable<TEntity> queryable, Expression secondExpression);
|
||||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -12,6 +13,7 @@ using ShardingCore.Core.VirtualTables;
|
||||||
using ShardingCore.DbContexts;
|
using ShardingCore.DbContexts;
|
||||||
using ShardingCore.DbContexts.Abstractions;
|
using ShardingCore.DbContexts.Abstractions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
using ShardingCore.TableCreator;
|
using ShardingCore.TableCreator;
|
||||||
|
|
||||||
namespace ShardingCore
|
namespace ShardingCore
|
||||||
|
@ -25,66 +27,58 @@ namespace ShardingCore
|
||||||
public class ShardingBootstrapper : IShardingBootstrapper
|
public class ShardingBootstrapper : IShardingBootstrapper
|
||||||
{
|
{
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly IShardingCoreOptions _shardingCoreOptions;
|
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions;
|
||||||
private readonly IVirtualTableManager _virtualTableManager;
|
private readonly IVirtualTableManager _virtualTableManager;
|
||||||
private readonly IShardingTableCreator _tableCreator;
|
private readonly IShardingTableCreator _tableCreator;
|
||||||
private readonly ILogger<ShardingBootstrapper> _logger;
|
private readonly ILogger<ShardingBootstrapper> _logger;
|
||||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||||
private readonly IDbContextCreateFilterManager _dbContextCreateFilterManager;
|
|
||||||
|
|
||||||
public ShardingBootstrapper(IServiceProvider serviceProvider, IShardingCoreOptions shardingCoreOptions,
|
public ShardingBootstrapper(IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions,
|
||||||
IVirtualTableManager virtualTableManager
|
IVirtualTableManager virtualTableManager
|
||||||
, IShardingTableCreator tableCreator, ILogger<ShardingBootstrapper> logger,
|
, IShardingTableCreator tableCreator, ILogger<ShardingBootstrapper> logger,
|
||||||
IShardingDbContextFactory shardingDbContextFactory,IDbContextCreateFilterManager dbContextCreateFilterManager)
|
IShardingDbContextFactory shardingDbContextFactory)
|
||||||
{
|
{
|
||||||
ShardingContainer.SetServices(serviceProvider);
|
ShardingContainer.SetServices(serviceProvider);
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
_shardingCoreOptions = shardingCoreOptions;
|
_shardingConfigOptions = shardingConfigOptions;
|
||||||
_virtualTableManager = virtualTableManager;
|
_virtualTableManager = virtualTableManager;
|
||||||
_tableCreator = tableCreator;
|
_tableCreator = tableCreator;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_shardingDbContextFactory = shardingDbContextFactory;
|
_shardingDbContextFactory = shardingDbContextFactory;
|
||||||
_dbContextCreateFilterManager = dbContextCreateFilterManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
foreach (var filter in _shardingCoreOptions.GetFilters())
|
|
||||||
{
|
|
||||||
_dbContextCreateFilterManager.RegisterFilter((IDbContextCreateFilter)Activator.CreateInstance(filter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var shardingConfig= _shardingCoreOptions.GetShardingConfig();
|
|
||||||
|
|
||||||
using var scope = _serviceProvider.CreateScope();
|
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
|
|
||||||
|
|
||||||
EnsureCreated(context);
|
|
||||||
foreach (var entity in context.Model.GetEntityTypes())
|
|
||||||
{
|
{
|
||||||
if (entity.ClrType.IsShardingTable())
|
foreach (var shardingConfigOption in _shardingConfigOptions)
|
||||||
{
|
{
|
||||||
var routeType = shardingConfig.DbConfigOptions.GetVirtualRoute(entity.ClrType);
|
using var context =
|
||||||
var virtualRoute = CreateVirtualRoute(routeType);
|
(DbContext) scope.ServiceProvider.GetService(shardingConfigOption.ShardingDbContextType);
|
||||||
var virtualTable = CreateVirtualTable(entity.ClrType, virtualRoute);
|
EnsureCreated(context);
|
||||||
|
foreach (var entity in context.Model.GetEntityTypes())
|
||||||
|
{
|
||||||
|
if (entity.ClrType.IsShardingTable())
|
||||||
|
{
|
||||||
|
var routeType = shardingConfigOption.GetVirtualRouteType(entity.ClrType);
|
||||||
|
var virtualRoute = CreateVirtualRoute(routeType);
|
||||||
|
var virtualTable = CreateVirtualTable(entity.ClrType, virtualRoute);
|
||||||
|
|
||||||
//获取ShardingEntity的实际表名
|
//获取ShardingEntity的实际表名
|
||||||
#if !EFCORE2
|
#if !EFCORE2
|
||||||
var tableName = context.Model.FindEntityType(virtualTable.EntityType).GetTableName();
|
var tableName = context.Model.FindEntityType(virtualTable.EntityType).GetTableName();
|
||||||
#endif
|
#endif
|
||||||
#if EFCORE2
|
#if EFCORE2
|
||||||
var tableName = context.Model.FindEntityType(virtualTable.EntityType).Relational().TableName;
|
var tableName = context.Model.FindEntityType(virtualTable.EntityType).Relational().TableName;
|
||||||
#endif
|
#endif
|
||||||
virtualTable.SetOriginalTableName(tableName);
|
virtualTable.SetOriginalTableName(tableName);
|
||||||
_virtualTableManager.AddVirtualTable(virtualTable);
|
_virtualTableManager.AddVirtualTable(shardingConfigOption.ShardingDbContextType,virtualTable);
|
||||||
CreateDataTable(virtualTable);
|
CreateDataTable(shardingConfigOption.ShardingDbContextType,virtualTable, shardingConfigOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,50 +118,51 @@ namespace ShardingCore
|
||||||
return (IVirtualTable) o;
|
return (IVirtualTable) o;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureCreated(DbContext context)
|
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)
|
lock (modelCacheSyncObject)
|
||||||
{
|
{
|
||||||
context.RemoveDbContextRelationModelThatIsShardingTable();
|
dbContext.RemoveDbContextRelationModelThatIsShardingTable();
|
||||||
context.Database.EnsureCreated();
|
dbContext.Database.EnsureCreated();
|
||||||
context.RemoveModelCache();
|
dbContext.RemoveModelCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool NeedCreateTable(ShardingTableConfig config)
|
private bool NeedCreateTable(ShardingTableConfig config, IShardingConfigOption shardingConfigOption)
|
||||||
{
|
{
|
||||||
if (config.AutoCreateTable.HasValue)
|
if (config.AutoCreateTable.HasValue)
|
||||||
{
|
{
|
||||||
return config.AutoCreateTable.Value;
|
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;
|
var shardingConfig = virtualTable.ShardingConfig;
|
||||||
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
|
foreach (var tail in virtualTable.GetVirtualRoute().GetAllTails())
|
||||||
{
|
{
|
||||||
if (NeedCreateTable(shardingConfig))
|
if (NeedCreateTable(shardingConfig, shardingConfigOption))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//添加物理表
|
//添加物理表
|
||||||
virtualTable.AddPhysicTable(new DefaultPhysicTable(virtualTable, tail));
|
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(
|
_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>();
|
return Services.GetService<T>();
|
||||||
}
|
}
|
||||||
|
public static object GetService(Type serviceType)
|
||||||
|
{
|
||||||
|
return Services.GetService(serviceType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
using System;
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ShardingCore.Core;
|
using ShardingCore.Core;
|
||||||
using ShardingCore.Exceptions;
|
using ShardingCore.Exceptions;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.TableCreator
|
namespace ShardingCore.TableCreator
|
||||||
{
|
{
|
||||||
|
@ -20,13 +22,14 @@ namespace ShardingCore.TableCreator
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tail"></param>
|
/// <param name="tail"></param>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <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>
|
||||||
/// 创建表
|
/// 创建表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType"></param>
|
||||||
/// <param name="shardingEntityType"></param>
|
/// <param name="shardingEntityType"></param>
|
||||||
/// <param name="tail"></param>
|
/// <param name="tail"></param>
|
||||||
/// <exception cref="ShardingCreateException"></exception>
|
/// <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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore.Storage;
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
@ -7,10 +9,12 @@ using Microsoft.Extensions.Logging;
|
||||||
using ShardingCore.Core;
|
using ShardingCore.Core;
|
||||||
using ShardingCore.Core.VirtualTables;
|
using ShardingCore.Core.VirtualTables;
|
||||||
using ShardingCore.DbContexts;
|
using ShardingCore.DbContexts;
|
||||||
|
using ShardingCore.DbContexts.Abstractions;
|
||||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||||
using ShardingCore.DbContexts.VirtualDbContexts;
|
using ShardingCore.DbContexts.VirtualDbContexts;
|
||||||
using ShardingCore.Exceptions;
|
using ShardingCore.Exceptions;
|
||||||
using ShardingCore.Extensions;
|
using ShardingCore.Extensions;
|
||||||
|
using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.TableCreator
|
namespace ShardingCore.TableCreator
|
||||||
{
|
{
|
||||||
|
@ -26,50 +30,60 @@ namespace ShardingCore.TableCreator
|
||||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||||
private readonly IVirtualTableManager _virtualTableManager;
|
private readonly IVirtualTableManager _virtualTableManager;
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly IShardingCoreOptions _shardingCoreOptions;
|
private readonly IEnumerable<IShardingConfigOption> _shardingConfigOptions;
|
||||||
|
|
||||||
public ShardingTableCreator(ILogger<ShardingTableCreator> logger, IShardingDbContextFactory shardingDbContextFactory,
|
public ShardingTableCreator(ILogger<ShardingTableCreator> logger, IShardingDbContextFactory shardingDbContextFactory,
|
||||||
IVirtualTableManager virtualTableManager, IServiceProvider serviceProvider,IShardingCoreOptions shardingCoreOptions)
|
IVirtualTableManager virtualTableManager, IServiceProvider serviceProvider, IEnumerable<IShardingConfigOption> shardingConfigOptions)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_shardingDbContextFactory = shardingDbContextFactory;
|
_shardingDbContextFactory = shardingDbContextFactory;
|
||||||
_virtualTableManager = virtualTableManager;
|
_virtualTableManager = virtualTableManager;
|
||||||
_serviceProvider = serviceProvider;
|
_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>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="shardingDbContextType"></param>
|
||||||
/// <param name="shardingEntityType"></param>
|
/// <param name="shardingEntityType"></param>
|
||||||
/// <param name="tail"></param>
|
/// <param name="tail"></param>
|
||||||
/// <exception cref="ShardingCreateException"></exception>
|
/// <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())
|
using (var serviceScope = _serviceProvider.CreateScope())
|
||||||
{
|
{
|
||||||
var dbContextOptionsProvider = serviceScope.ServiceProvider.GetService<IDbContextOptionsProvider>();
|
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntityType);
|
||||||
var virtualTable = _virtualTableManager.GetVirtualTable(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 = context.GetModelCacheSyncObject();
|
||||||
{
|
|
||||||
var modelCacheSyncObject = dbContext.GetModelCacheSyncObject();
|
|
||||||
|
|
||||||
lock (modelCacheSyncObject)
|
lock (modelCacheSyncObject)
|
||||||
{
|
{
|
||||||
dbContext.RemoveDbContextRelationModelSaveOnlyThatIsNamedType(shardingEntityType);
|
context.RemoveDbContextRelationModelSaveOnlyThatIsNamedType(shardingEntityType);
|
||||||
var databaseCreator = dbContext.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
|
var databaseCreator = context.Database.GetService<IDatabaseCreator>() as RelationalDatabaseCreator;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
databaseCreator.CreateTables();
|
databaseCreator.CreateTables();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (!_shardingCoreOptions.IgnoreCreateTableError.GetValueOrDefault())
|
if (!shardingConfigOptions.IgnoreCreateTableError.GetValueOrDefault())
|
||||||
{
|
{
|
||||||
_logger.LogWarning(
|
_logger.LogWarning(
|
||||||
$"create table error maybe table:[{virtualTable.GetOriginalTableName()}{virtualTable.ShardingConfig.TailPrefix}{tail}]");
|
$"create table error maybe table:[{virtualTable.GetOriginalTableName()}{virtualTable.ShardingConfig.TailPrefix}{tail}]");
|
||||||
|
@ -78,11 +92,10 @@ namespace ShardingCore.TableCreator
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
dbContext.RemoveModelCache();
|
context.RemoveModelCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.2" />
|
<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="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
<PackageReference Include="Xunit.DependencyInjection" Version="7.1.0" />
|
<PackageReference Include="Xunit.DependencyInjection" Version="7.1.0" />
|
||||||
|
@ -22,5 +23,8 @@
|
||||||
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\ShardingCore\ShardingCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -28,5 +28,7 @@ namespace ShardingCore.Test50
|
||||||
modelBuilder.ApplyConfiguration(new SysUserModMap());
|
modelBuilder.ApplyConfiguration(new SysUserModMap());
|
||||||
modelBuilder.ApplyConfiguration(new SysUserSalaryMap());
|
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.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
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.Domain.Entities;
|
||||||
using ShardingCore.Test50.Shardings;
|
using ShardingCore.Test50.Shardings;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
#if EFCORE5SQLSERVER
|
#if EFCORE5SQLSERVER
|
||||||
using ShardingCore.SqlServer;
|
using ShardingCore.SqlServer;
|
||||||
|
@ -22,14 +19,18 @@ using ShardingCore.MySql;
|
||||||
|
|
||||||
namespace ShardingCore.Test50
|
namespace ShardingCore.Test50
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* @Author: xjm
|
* @Author: xjm
|
||||||
* @Description:
|
* @Description:
|
||||||
* @Date: Friday, 15 January 2021 15:37:46
|
* @Date: Friday, 15 January 2021 15:37:46
|
||||||
* @Email: 326308290@qq.com
|
* @Email: 326308290@qq.com
|
||||||
*/
|
*/
|
||||||
public class Startup
|
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 构建
|
// // 自定义 host 构建
|
||||||
public void ConfigureHost(IHostBuilder hostBuilder)
|
public void ConfigureHost(IHostBuilder hostBuilder)
|
||||||
{
|
{
|
||||||
|
@ -47,33 +48,18 @@ namespace ShardingCore.Test50
|
||||||
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
public void ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
|
||||||
{
|
{
|
||||||
|
|
||||||
services.AddShardingSqlServer(o =>
|
services.AddDbContext<DefaultDbContext>(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"]));
|
o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]));
|
||||||
services.AddDbContext<ShardingDefaultDbContext>(o=>
|
services.AddShardingDbContext<ShardingDefaultDbContext, DefaultDbContext>(o =>
|
||||||
o.UseSqlServer(hostBuilderContext.Configuration.GetSection("SqlServer")["ConnectionString"]).UseSharding());
|
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 方法
|
// 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法
|
||||||
|
@ -90,50 +76,50 @@ namespace ShardingCore.Test50
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serviceProvider"></param>
|
/// <param name="serviceProvider"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task InitData(IServiceProvider serviceProvider)
|
private async Task InitData(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
using (var scope = serviceProvider.CreateScope())
|
using (var scope = serviceProvider.CreateScope())
|
||||||
{
|
{
|
||||||
var virtualDbContext = scope.ServiceProvider.GetService<ShardingDefaultDbContext>();
|
var virtualDbContext = scope.ServiceProvider.GetService<ShardingDefaultDbContext>();
|
||||||
var ids = Enumerable.Range(1, 1000);
|
var ids = Enumerable.Range(1, 1000);
|
||||||
var userMods = new List<SysUserMod>();
|
var userMods = new List<SysUserMod>();
|
||||||
var userSalaries = new List<SysUserSalary>();
|
var userSalaries = new List<SysUserSalary>();
|
||||||
var beginTime = new DateTime(2020, 1, 1);
|
var beginTime = new DateTime(2020, 1, 1);
|
||||||
var endTime = new DateTime(2021, 12, 1);
|
var endTime = new DateTime(2021, 12, 1);
|
||||||
foreach (var id in ids)
|
foreach (var id in ids)
|
||||||
|
{
|
||||||
|
userMods.Add(new SysUserMod()
|
||||||
{
|
{
|
||||||
userMods.Add(new SysUserMod()
|
Id = id.ToString(),
|
||||||
|
Age = id,
|
||||||
|
Name = $"name_{id}",
|
||||||
|
AgeGroup = Math.Abs(id % 10)
|
||||||
|
});
|
||||||
|
var tempTime = beginTime;
|
||||||
|
var i = 0;
|
||||||
|
while (tempTime <= endTime)
|
||||||
|
{
|
||||||
|
var dateOfMonth = $@"{tempTime:yyyyMM}";
|
||||||
|
userSalaries.Add(new SysUserSalary()
|
||||||
{
|
{
|
||||||
Id = id.ToString(),
|
Id = $@"{id}{dateOfMonth}",
|
||||||
Age = id,
|
UserId = id.ToString(),
|
||||||
Name = $"name_{id}",
|
DateOfMonth = int.Parse(dateOfMonth),
|
||||||
AgeGroup=Math.Abs(id%10)
|
Salary = 700000 + id * 100 * i,
|
||||||
|
SalaryLong = 700000 + id * 100 * i,
|
||||||
|
SalaryDecimal = (700000 + id * 100 * i) / 100m,
|
||||||
|
SalaryDouble = (700000 + id * 100 * i) / 100d,
|
||||||
|
SalaryFloat = (700000 + id * 100 * i) / 100f
|
||||||
});
|
});
|
||||||
var tempTime = beginTime;
|
tempTime = tempTime.AddMonths(1);
|
||||||
var i = 0;
|
i++;
|
||||||
while (tempTime<=endTime)
|
|
||||||
{
|
|
||||||
var dateOfMonth = $@"{tempTime:yyyyMM}";
|
|
||||||
userSalaries.Add(new SysUserSalary()
|
|
||||||
{
|
|
||||||
Id = $@"{id}{dateOfMonth}",
|
|
||||||
UserId = id.ToString(),
|
|
||||||
DateOfMonth = int.Parse(dateOfMonth),
|
|
||||||
Salary = 700000+id*100*i,
|
|
||||||
SalaryLong = 700000+id*100*i,
|
|
||||||
SalaryDecimal = (700000+id*100*i)/100m,
|
|
||||||
SalaryDouble = (700000+id*100*i)/100d,
|
|
||||||
SalaryFloat = (700000+id*100*i)/100f
|
|
||||||
});
|
|
||||||
tempTime=tempTime.AddMonths(1);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await virtualDbContext.AddRangeAsync(userMods);
|
await virtualDbContext.AddRangeAsync(userMods);
|
||||||
await virtualDbContext.AddRangeAsync(userSalaries);
|
await virtualDbContext.AddRangeAsync(userSalaries);
|
||||||
|
|
||||||
await virtualDbContext.SaveChangesAsync();
|
await virtualDbContext.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue