创建移除efcore2的分表基本
This commit is contained in:
parent
8f665394ff
commit
1c1d6cf965
|
@ -11,10 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src3x", "src3x", "{62AAE0FE
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.3x", "src3x\ShardingCore.3x\ShardingCore.3x.csproj", "{E0FDBFA9-AE5F-42FB-8A60-4E5D9E7D5414}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src2x", "src2x", "{679E6084-0C45-4807-BFEE-D2FDA44B2188}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.2x", "src2x\ShardingCore.2x\ShardingCore.2x.csproj", "{FB92A4BE-A43E-4755-8132-EC38E9650B80}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CC2C88C0-65F2-445D-BE78-973B840FE281}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.Test50", "test\ShardingCore.Test50\ShardingCore.Test50.csproj", "{7EE133B6-5A02-41B7-9D89-41D9EA14184E}"
|
||||
|
@ -35,9 +31,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Samples.AbpSharding", "samp
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.Test50_3x", "test\ShardingCore.Test50_3x\ShardingCore.Test50_3x.csproj", "{C0A59BB0-F0B8-4AC6-B192-0249E784FC88}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ShardingCore.Test50_2x", "test\ShardingCore.Test50_2x\ShardingCore.Test50_2x.csproj", "{6709DD6A-6A44-4A49-BA4D-A50A40102C8B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.BulkConsole", "samples\Sample.BulkConsole\Sample.BulkConsole.csproj", "{2443CC8B-FB7D-47A7-9663-F3848BB30A36}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.BulkConsole", "samples\Sample.BulkConsole\Sample.BulkConsole.csproj", "{2443CC8B-FB7D-47A7-9663-F3848BB30A36}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -53,10 +47,6 @@ Global
|
|||
{E0FDBFA9-AE5F-42FB-8A60-4E5D9E7D5414}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E0FDBFA9-AE5F-42FB-8A60-4E5D9E7D5414}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E0FDBFA9-AE5F-42FB-8A60-4E5D9E7D5414}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FB92A4BE-A43E-4755-8132-EC38E9650B80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FB92A4BE-A43E-4755-8132-EC38E9650B80}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FB92A4BE-A43E-4755-8132-EC38E9650B80}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FB92A4BE-A43E-4755-8132-EC38E9650B80}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7EE133B6-5A02-41B7-9D89-41D9EA14184E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7EE133B6-5A02-41B7-9D89-41D9EA14184E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7EE133B6-5A02-41B7-9D89-41D9EA14184E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -89,10 +79,6 @@ Global
|
|||
{C0A59BB0-F0B8-4AC6-B192-0249E784FC88}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0A59BB0-F0B8-4AC6-B192-0249E784FC88}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C0A59BB0-F0B8-4AC6-B192-0249E784FC88}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6709DD6A-6A44-4A49-BA4D-A50A40102C8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6709DD6A-6A44-4A49-BA4D-A50A40102C8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6709DD6A-6A44-4A49-BA4D-A50A40102C8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6709DD6A-6A44-4A49-BA4D-A50A40102C8B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2443CC8B-FB7D-47A7-9663-F3848BB30A36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2443CC8B-FB7D-47A7-9663-F3848BB30A36}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2443CC8B-FB7D-47A7-9663-F3848BB30A36}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -104,7 +90,6 @@ Global
|
|||
GlobalSection(NestedProjects) = preSolution
|
||||
{3CAF09A6-6ABD-41D9-BA57-9A822B8095F7} = {490FAE47-4476-4508-B216-505FC850447F}
|
||||
{E0FDBFA9-AE5F-42FB-8A60-4E5D9E7D5414} = {62AAE0FE-4099-4A48-AA3C-F76F14C62655}
|
||||
{FB92A4BE-A43E-4755-8132-EC38E9650B80} = {679E6084-0C45-4807-BFEE-D2FDA44B2188}
|
||||
{7EE133B6-5A02-41B7-9D89-41D9EA14184E} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
||||
{D48E5EC2-CF83-4B17-8BBA-BDE52ADFAB1F} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
{C8FAB96F-F13E-4094-883C-2D38D39EE4A3} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
||||
|
@ -113,7 +98,6 @@ Global
|
|||
{447D5357-F095-45DE-9DA5-2D9997237366} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
{1136B8C9-3539-42FA-97FD-CAA6F146FCF0} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
{C0A59BB0-F0B8-4AC6-B192-0249E784FC88} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
||||
{6709DD6A-6A44-4A49-BA4D-A50A40102C8B} = {CC2C88C0-65F2-445D-BE78-973B840FE281}
|
||||
{2443CC8B-FB7D-47A7-9663-F3848BB30A36} = {EDF8869A-C1E1-491B-BC9F-4A33F4DE1C73}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
:start
|
||||
::定义版本
|
||||
set EFCORE2=2.2.0.20
|
||||
set EFCORE3=3.2.0.20
|
||||
set EFCORE5=5.2.0.20
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.BulkConsole.Entities;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace Sample.BulkConsole.DbContexts
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace Sample.BulkConsole
|
|||
|
||||
Console.WriteLine("ok");
|
||||
}
|
||||
|
||||
var b = DateTime.Now.Date.AddDays(-3);
|
||||
var queryable = myShardingDbContext.Set<Order>().Where(o => o.CreateTime >= b).OrderBy(o => o.CreateTime);
|
||||
var startNew1 = Stopwatch.StartNew();
|
||||
|
|
|
@ -74,6 +74,7 @@ namespace Sample.SqlServer.Controllers
|
|||
var sysUserMod98 = result.FirstOrDefault(o => o.Id == "98");
|
||||
_defaultTableDbContext.Attach(sysUserMod98);
|
||||
sysUserMod98.Name = "name_update" + new Random().Next(1, 99) + "_98";
|
||||
_defaultTableDbContext.Attach(sysUserMod98);
|
||||
await _defaultTableDbContext.SaveChangesAsync();
|
||||
var stu = new STU() { Id = "198" };
|
||||
var sresultx111x = _defaultTableDbContext.Set<SysUserMod>().FirstOrDefault(o => o.Id == stu.Id);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.SqlServer.Domain.Maps;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace Sample.SqlServer.DbContexts
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Samples.AutoByDate.SqlServer.Domain.Maps;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace Samples.AutoByDate.SqlServer.DbContexts
|
||||
|
|
|
@ -17,31 +17,31 @@ namespace Samples.AutoByDate.SqlServer.Jobs
|
|||
*/
|
||||
public class AutoCreateTableByDay : IJob
|
||||
{
|
||||
/// <summary>
|
||||
/// 每天中午12点执行,启动的时候执行以下
|
||||
/// </summary>
|
||||
/// <param name="virtualTableManager"></param>
|
||||
/// <param name="tableCreator"></param>
|
||||
[JobRun(Name = "定时创建分表组件", Cron = "0 0 12 * * ?", RunOnceOnStart = true)]
|
||||
///// <summary>
|
||||
///// 每天中午12点执行,启动的时候执行以下
|
||||
///// </summary>
|
||||
///// <param name="virtualTableManager"></param>
|
||||
///// <param name="tableCreator"></param>
|
||||
//[JobRun(Name = "定时创建分表组件", Cron = "0 0 12 * * ?", RunOnceOnStart = true)]
|
||||
|
||||
public void AutoCreateTable(IVirtualTableManager virtualTableManager, IShardingTableCreator tableCreator)
|
||||
{
|
||||
var virtualTable = virtualTableManager.GetVirtualTable<DefaultShardingDbContext, SysUserLogByDay>();
|
||||
if (virtualTable == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var now = DateTime.Now.Date.AddDays(1);
|
||||
var tail = virtualTable.GetVirtualRoute().ShardingKeyToTail(now);
|
||||
try
|
||||
{
|
||||
virtualTableManager.AddPhysicTable<DefaultShardingDbContext>(virtualTable, new DefaultPhysicTable(virtualTable, tail));
|
||||
tableCreator.CreateTable<DefaultShardingDbContext, SysUserLogByDay>(tail);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
//public void AutoCreateTable(IVirtualTableManager virtualTableManager, IShardingTableCreator tableCreator)
|
||||
//{
|
||||
// var virtualTable = virtualTableManager.GetVirtualTable<DefaultShardingDbContext, SysUserLogByDay>();
|
||||
// if (virtualTable == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// var now = DateTime.Now.Date.AddDays(1);
|
||||
// var tail = virtualTable.GetVirtualRoute().ShardingKeyToTail(now);
|
||||
// try
|
||||
// {
|
||||
// virtualTableManager.AddPhysicTable<DefaultShardingDbContext>(virtualTable, new DefaultPhysicTable(virtualTable, tail));
|
||||
// tableCreator.CreateTable<DefaultShardingDbContext, SysUserLogByDay>(tail);
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// //ignore
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
namespace ShardingCore.Core
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 16 December 2020 10:41:27
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingTable
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -20,18 +20,19 @@ namespace ShardingCore.Core.PhysicTables
|
|||
VirtualTable = virtualTable;
|
||||
OriginalName = virtualTable.GetOriginalTableName();
|
||||
Tail = tail;
|
||||
EntityType = VirtualTable.EntityType;
|
||||
}
|
||||
|
||||
|
||||
public string FullName => $"{OriginalName}{TailPrefix}{Tail}";
|
||||
public string OriginalName { get; }
|
||||
public string TailPrefix =>VirtualTable.ShardingConfig.TailPrefix;
|
||||
public string Tail { get; }
|
||||
public Type EntityType => VirtualTable.EntityType;
|
||||
public Type EntityType { get; }
|
||||
public IVirtualTable VirtualTable { get; }
|
||||
|
||||
protected bool Equals(DefaultPhysicTable other)
|
||||
{
|
||||
return OriginalName == other.OriginalName && Tail == other.Tail && Equals(VirtualTable, other.VirtualTable);
|
||||
return OriginalName == other.OriginalName && Tail == other.Tail && Equals(EntityType, other.EntityType);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -39,29 +40,13 @@ namespace ShardingCore.Core.PhysicTables
|
|||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((DefaultPhysicTable) obj);
|
||||
return Equals((DefaultPhysicTable)obj);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(OriginalName, Tail, VirtualTable);
|
||||
return HashCode.Combine(OriginalName, Tail, EntityType);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = (OriginalName != null ? OriginalName.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (Tail != null ? Tail.GetHashCode() : 0);
|
||||
hashCode = (hashCode * 397) ^ (VirtualTable != null ? VirtualTable.GetHashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ namespace ShardingCore.Core.PhysicTables
|
|||
*/
|
||||
public interface IPhysicTable
|
||||
{
|
||||
string DSName { get;}
|
||||
/// <summary>
|
||||
/// 表全称
|
||||
/// </summary>
|
||||
|
|
|
@ -17,8 +17,9 @@ namespace ShardingCore.Core.QueryRouteManagers
|
|||
{
|
||||
private static AsyncLocal<ShardingRouteContext> _shardingRouteContext = new AsyncLocal<ShardingRouteContext>();
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// sharding route context use in using code block
|
||||
/// </summary>
|
||||
public ShardingRouteContext ShardingRouteContext
|
||||
{
|
||||
get => _shardingRouteContext.Value;
|
||||
|
|
|
@ -14,5 +14,9 @@ namespace ShardingCore.Core
|
|||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
|
||||
public class ShardingDataSourceKeyAttribute: Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否需要在启动的时候创建表
|
||||
/// </summary>
|
||||
public ShardingKeyAutoCreateDataSourceEnum AutoCreateDataSourceOnStart { get; set; } = ShardingKeyAutoCreateDataSourceEnum.UnKnown;
|
||||
}
|
||||
}
|
|
@ -1,18 +1,20 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core.Internal
|
||||
namespace ShardingCore.Core.VirtualDatabase
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 05 February 2021 13:34:29
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingEntityBaseType
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 9:30:04
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingEntityConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据源
|
||||
/// 分表类型 sharding entity type
|
||||
/// </summary>
|
||||
public Type EntityType { get; set; }
|
||||
/// <summary>
|
||||
|
@ -22,19 +24,26 @@ namespace ShardingCore.Core.Internal
|
|||
/// <summary>
|
||||
/// 是否分表
|
||||
/// </summary>
|
||||
public bool IsMultiTableMapping { get;set; }
|
||||
public bool IsMultiTableMapping { get; set; }
|
||||
/// <summary>
|
||||
/// 分库字段
|
||||
/// </summary>
|
||||
public string ShardingDataSourceField { get;set; }
|
||||
public string ShardingDataSourceField { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分表字段
|
||||
/// 启动时是否建表 auto create data source when start app
|
||||
/// </summary>
|
||||
public bool? AutoCreateDataSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分表字段 sharding table field
|
||||
/// </summary>
|
||||
public string ShardingTableField { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分表的原表名 original table name in db exclude tail
|
||||
/// </summary>
|
||||
public string ShardingOriginalTableName { get; set; }
|
||||
public string OriginalTableName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 启动时是否建表 auto create table when start app
|
||||
|
@ -46,4 +55,4 @@ namespace ShardingCore.Core.Internal
|
|||
/// </summary>
|
||||
public string TailPrefix { get; set; } = "_";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 05 February 2021 13:01:39
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 虚拟数据源 连接所有的实际数据源
|
||||
/// </summary>
|
||||
public interface IVirtualDataSource
|
||||
{
|
||||
Type EntityType{get;}
|
||||
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
List<IPhysicDataSource> RouteTo(ShardingDataSourceRouteConfig routeRouteConfig);
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前数据源的路由
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IVirtualDataSourceRoute GetRoute();
|
||||
|
||||
ISet<IPhysicDataSource> GetAllPhysicDataSources();
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic data source
|
||||
/// </summary>
|
||||
/// <param name="physicDataSource"></param>
|
||||
/// <returns>是否添加成功</returns>
|
||||
bool AddPhysicDataSource(IPhysicDataSource physicDataSource);
|
||||
|
||||
/// <summary>
|
||||
/// add virtual table
|
||||
/// </summary>
|
||||
/// <param name="dsname"></param>
|
||||
/// <param name="virtualTable"></param>
|
||||
/// <returns></returns>
|
||||
bool AddVirtualTable(string dsname, IVirtualTable virtualTable);
|
||||
/// <summary>
|
||||
/// 获取所有的虚拟表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
ISet<IVirtualTable> GetVirtualTables();
|
||||
}
|
||||
public interface IVirtualDataSource<T> : IVirtualDataSource where T : class
|
||||
{
|
||||
new IVirtualDataSourceRoute<T> GetRoute();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDataSources
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 06 February 2021 14:24:01
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IVirtualDataSourceManager
|
||||
{
|
||||
IPhysicDataSource GetDataSource(string dsName);
|
||||
/// <summary>
|
||||
/// 添加链接
|
||||
/// </summary>
|
||||
/// <param name="physicDataSource"></param>
|
||||
void AddPhysicDataSource(IPhysicDataSource physicDataSource);
|
||||
/// <summary>
|
||||
/// 获取默认的数据源
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType"></param>
|
||||
/// <returns></returns>
|
||||
IPhysicDataSource GetDefaultDataSource(Type shardingDbContextType);
|
||||
IVirtualDataSource GetVirtualDataSource(Type shardingDbContextType, Type entityType);
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IVirtualDataSource<T> GetVirtualDataSource<T>() where T : class, IShardingDataSource;
|
||||
/// <summary>
|
||||
/// 获取
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType"></param>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
List<IPhysicDataSource> GetDefaultDataSources(Type shardingDbContextType,Type entityType);
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加虚拟数据源应用启动时 add virtual table when app start
|
||||
/// </summary>
|
||||
/// <param name="virtualDataSource"></param>
|
||||
void AddVirtualDataSource(IVirtualDataSource virtualDataSource);
|
||||
|
||||
/// <summary>
|
||||
/// 添加链接对应的对象
|
||||
/// </summary>
|
||||
/// <param name="connectKey"></param>
|
||||
/// <param name="entityType"></param>
|
||||
void AddConnectEntities(string connectKey,Type entityType);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
/// </summary>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualDataSource GetVirtualDataSource(Type shardingEntityType);
|
||||
|
||||
|
||||
List<string> GetEntityTypeLinkedConnectKeys(Type shardingEntityType);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ShardingCore.Core.VirtualDataSources;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 10:33:56
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DefaultPhysicDataSource:IPhysicDataSource
|
||||
{
|
||||
public DefaultPhysicDataSource(string dsName, string connectionString, IVirtualDataSource virtualDataSource)
|
||||
{
|
||||
DSName = dsName;
|
||||
ConnectionString = connectionString;
|
||||
VirtualDataSource = virtualDataSource;
|
||||
EntityType = virtualDataSource.EntityType;
|
||||
}
|
||||
|
||||
|
||||
public string DSName { get; }
|
||||
public string ConnectionString { get; }
|
||||
public Type EntityType { get; }
|
||||
public IVirtualDataSource VirtualDataSource { get; }
|
||||
|
||||
|
||||
protected bool Equals(DefaultPhysicDataSource other)
|
||||
{
|
||||
return DSName == other.DSName;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((DefaultPhysicDataSource)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (DSName != null ? DSName.GetHashCode() : 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using ShardingCore.Core.VirtualDataSources;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 9:10:53
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IPhysicDataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// data source name
|
||||
/// </summary>
|
||||
string DSName { get; }
|
||||
/// <summary>
|
||||
/// 数据源链接
|
||||
/// </summary>
|
||||
string ConnectionString { get; }
|
||||
/// <summary>
|
||||
/// 映射类类型
|
||||
/// </summary>
|
||||
Type EntityType { get; }
|
||||
IVirtualDataSource VirtualDataSource { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Utils;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 05 February 2021 15:21:04
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class VirtualDataSource<T>:IVirtualDataSource<T> where T:class
|
||||
{
|
||||
private readonly IVirtualDataSourceRoute<T> _dataSourceVirtualRoute;
|
||||
public ShardingEntityConfig ShardingEntityType { get; }
|
||||
|
||||
public Type EntityType { get; }
|
||||
private readonly ConcurrentDictionary<IPhysicDataSource, object> _physicDataSources = new ConcurrentDictionary<IPhysicDataSource, object>();
|
||||
|
||||
|
||||
private readonly ConcurrentDictionary<string, IVirtualTable> _virtualTables =
|
||||
new ConcurrentDictionary<string, IVirtualTable>();
|
||||
|
||||
public VirtualDataSource(IVirtualDataSourceRoute<T> virtualRoute)
|
||||
{
|
||||
_dataSourceVirtualRoute = virtualRoute;
|
||||
EntityType = typeof(T);
|
||||
ShardingEntityType = ShardingUtil.Parse(EntityType);
|
||||
}
|
||||
|
||||
|
||||
public List<IPhysicDataSource> RouteTo(ShardingDataSourceRouteConfig routeRouteConfig)
|
||||
{
|
||||
|
||||
if (routeRouteConfig.UseQueryable())
|
||||
return _dataSourceVirtualRoute.RouteWithWhere(GetAllPhysicDataSources(), routeRouteConfig.GetQueryable());
|
||||
if (routeRouteConfig.UsePredicate())
|
||||
return _dataSourceVirtualRoute.RouteWithWhere(GetAllPhysicDataSources(), new EnumerableQuery<T>((Expression<Func<T, bool>>) routeRouteConfig.GetPredicate()));
|
||||
object shardingKeyValue = null;
|
||||
if (routeRouteConfig.UseValue())
|
||||
shardingKeyValue = routeRouteConfig.GetShardingKeyValue();
|
||||
|
||||
if (routeRouteConfig.UseEntity())
|
||||
shardingKeyValue = routeRouteConfig.GetShardingDataSource().GetPropertyValue(ShardingEntityType.ShardingDataSourceField);
|
||||
|
||||
if (shardingKeyValue != null)
|
||||
{
|
||||
var routeWithValue = _dataSourceVirtualRoute.RouteWithValue(GetAllPhysicDataSources(), shardingKeyValue);
|
||||
return new List<IPhysicDataSource>(1) {routeWithValue};
|
||||
}
|
||||
|
||||
throw new NotImplementedException(nameof(ShardingDataSourceRouteConfig));
|
||||
}
|
||||
|
||||
IVirtualDataSourceRoute<T> IVirtualDataSource<T>.GetRoute()
|
||||
{
|
||||
return _dataSourceVirtualRoute;
|
||||
}
|
||||
|
||||
public IVirtualDataSourceRoute GetRoute()
|
||||
{
|
||||
return _dataSourceVirtualRoute;
|
||||
}
|
||||
|
||||
public ISet<IPhysicDataSource> GetAllPhysicDataSources()
|
||||
{
|
||||
return _physicDataSources.Keys.ToHashSet();
|
||||
}
|
||||
|
||||
public bool AddPhysicDataSource(IPhysicDataSource physicDataSource)
|
||||
{
|
||||
if (physicDataSource.EntityType != EntityType)
|
||||
throw new InvalidOperationException($"virtual data source entity type :[{EntityType.FullName}] physic data source entity type:[{physicDataSource.EntityType.FullName}]");
|
||||
return _physicDataSources.TryAdd(physicDataSource, null);
|
||||
}
|
||||
|
||||
public bool AddVirtualTable(string dsname, IVirtualTable virtualTable)
|
||||
{
|
||||
if (virtualTable.EntityType != EntityType)
|
||||
throw new InvalidOperationException($"virtual data source entity:{EntityType.FullName},virtual table entity:{virtualTable.EntityType.FullName}");
|
||||
if (_physicDataSources.Keys.All(o => o.DSName != dsname))
|
||||
throw new InvalidOperationException($"data source name:[{dsname}] not found virtual data source");
|
||||
return _virtualTables.TryAdd(dsname, virtualTable);
|
||||
}
|
||||
|
||||
public ISet<IVirtualTable> GetVirtualTables()
|
||||
{
|
||||
return _virtualTables.Values.ToHashSet();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Helpers;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDataSources
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 06 February 2021 15:24:08
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class VirtualDataSourceManager : IVirtualDataSourceManager
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ConcurrentDictionary<Type, IVirtualDataSource> _virtualDataSources = new ConcurrentDictionary<Type, IVirtualDataSource>();
|
||||
|
||||
private readonly Dictionary<string, ISet<Type>> _shardingConnectKeys = new Dictionary<string,ISet<Type>>();
|
||||
private readonly Dictionary<Type, ISet<string>> _entityTypeConnectKeyIndex = new Dictionary<Type, ISet<string>>();
|
||||
|
||||
public VirtualDataSourceManager(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
//var shardingEntities = AssemblyHelper.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes())
|
||||
// .Where(type => !String.IsNullOrEmpty(type.Namespace))
|
||||
// .Where(type => !type.IsAbstract&&type.GetInterfaces()
|
||||
// .Any(it => it.IsInterface &&typeof(IShardingDataSource)==it)
|
||||
// );
|
||||
//foreach (var shardingEntity in shardingEntities)
|
||||
//{
|
||||
// Type genericType = typeof(IVirtualDataSource<>);
|
||||
// Type interfaceType = genericType.MakeGenericType(shardingEntity);
|
||||
// var virtualDataSource = (IVirtualDataSource)serviceProvider.GetService(interfaceType);
|
||||
// _virtualDataSources.TryAdd(virtualDataSource.EntityType, virtualDataSource);
|
||||
//}
|
||||
}
|
||||
|
||||
public ISet<string> GetAllShardingConnectKeys()
|
||||
{
|
||||
return _shardingConnectKeys.Keys.ToHashSet();
|
||||
}
|
||||
|
||||
|
||||
public List<IVirtualDataSource> GetAllDataSources()
|
||||
{
|
||||
return _virtualDataSources.Select(o => o.Value).ToList();
|
||||
}
|
||||
|
||||
public void AddConnectEntities(string connectKey, Type entityType)
|
||||
{
|
||||
if (!_shardingConnectKeys.ContainsKey(connectKey))
|
||||
throw new ShardingCoreException("connectKey not init");
|
||||
_shardingConnectKeys[connectKey].Add(entityType);
|
||||
BuildIndex(connectKey, entityType);
|
||||
}
|
||||
|
||||
private void BuildIndex(string connectKey, Type entityType)
|
||||
{
|
||||
|
||||
if (_entityTypeConnectKeyIndex.ContainsKey(entityType))
|
||||
{
|
||||
_entityTypeConnectKeyIndex[entityType].Add(connectKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
_entityTypeConnectKeyIndex.Add(entityType,new HashSet<string>(){ connectKey
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public IVirtualDataSource GetVirtualDataSource(Type shardingEntityType)
|
||||
{
|
||||
if (!_virtualDataSources.TryGetValue(shardingEntityType, out var virtualTable) || virtualTable == null)
|
||||
throw new VirtualDataSourceNotFoundException($"{shardingEntityType}");
|
||||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualDataSource<T> GetVirtualDataSource<T>() where T : class, IShardingDataSource
|
||||
{
|
||||
return (IVirtualDataSource<T>)GetVirtualDataSource(typeof(T));
|
||||
}
|
||||
|
||||
public List<string> GetEntityTypeLinkedConnectKeys(Type shardingEntityType)
|
||||
{
|
||||
if (!_entityTypeConnectKeyIndex.ContainsKey(shardingEntityType))
|
||||
throw new ShardingCoreException($"entity:[{shardingEntityType}] not found");
|
||||
return _entityTypeConnectKeyIndex[shardingEntityType].ToList();
|
||||
}
|
||||
|
||||
public void AddShardingConnectKey(string connectKey)
|
||||
{
|
||||
if (!_shardingConnectKeys.ContainsKey(connectKey))
|
||||
_shardingConnectKeys.Add(connectKey,new HashSet<Type>());
|
||||
}
|
||||
|
||||
public void AddVirtualDataSource(IVirtualDataSource virtualDataSource)
|
||||
{
|
||||
_virtualDataSources.TryAdd(virtualDataSource.EntityType, virtualDataSource);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ using System.Collections.Concurrent;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
|
||||
namespace ShardingCore.Core.VirtualTables
|
||||
{
|
||||
|
@ -22,22 +23,39 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// 同数据库虚拟表
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class OneDbVirtualTable<T> : IVirtualTable<T> where T : class, IShardingTable
|
||||
public class DefaultVirtualTable<T> : IVirtualTable<T> where T : class
|
||||
{
|
||||
private readonly IVirtualTableRoute<T> _virtualTableRoute;
|
||||
public string DSName { get; }
|
||||
|
||||
public Type EntityType => typeof(T);
|
||||
/// <summary>
|
||||
/// 分表的对象类型
|
||||
/// </summary>
|
||||
public Type EntityType { get; }
|
||||
/// <summary>
|
||||
/// 分表的配置
|
||||
/// </summary>
|
||||
public ShardingTableConfig ShardingConfig { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 分库配置
|
||||
/// </summary>
|
||||
public PaginationMetadata PaginationMetadata { get; }
|
||||
/// <summary>
|
||||
/// 是否启用智能分页
|
||||
/// </summary>
|
||||
public bool EnablePagination => PaginationMetadata != null;
|
||||
|
||||
private readonly ConcurrentDictionary<IPhysicTable,object> _physicTables = new ConcurrentDictionary<IPhysicTable,object>();
|
||||
public IVirtualDataSource VirtualDataSource { get; }
|
||||
|
||||
public OneDbVirtualTable(IVirtualTableRoute<T> virtualTableRoute)
|
||||
private readonly ConcurrentDictionary<IPhysicTable, object> _physicTables = new ConcurrentDictionary<IPhysicTable, object>();
|
||||
|
||||
public DefaultVirtualTable(string dsname,IVirtualDataSource<T> virtualDataSource,IVirtualTableRoute<T> virtualTableRoute)
|
||||
{
|
||||
_virtualTableRoute = virtualTableRoute;
|
||||
DSName = dsname;
|
||||
_virtualTableRoute = virtualTableRoute;
|
||||
EntityType = typeof(T);
|
||||
ShardingConfig = ShardingKeyUtil.Parse(EntityType);
|
||||
VirtualDataSource = virtualDataSource;
|
||||
var paginationConfiguration = virtualTableRoute.CreatePaginationConfiguration();
|
||||
if (paginationConfiguration != null)
|
||||
{
|
||||
|
@ -52,13 +70,13 @@ namespace ShardingCore.Core.VirtualTables
|
|||
return _physicTables.Keys.ToList();
|
||||
}
|
||||
|
||||
public List<IPhysicTable> RouteTo(TableRouteConfig tableRouteConfig)
|
||||
public List<IPhysicTable> RouteTo(ShardingTableRouteConfig tableRouteConfig)
|
||||
{
|
||||
var route = _virtualTableRoute;
|
||||
if (tableRouteConfig.UseQueryable())
|
||||
return route.RouteWithPredicate(GetAllPhysicTables(), tableRouteConfig.GetQueryable(),true);
|
||||
return route.RouteWithPredicate(GetAllPhysicTables(), tableRouteConfig.GetQueryable(), true);
|
||||
if (tableRouteConfig.UsePredicate())
|
||||
return route.RouteWithPredicate(GetAllPhysicTables(), new EnumerableQuery<T>((Expression<Func<T, bool>>) tableRouteConfig.GetPredicate()),false);
|
||||
return route.RouteWithPredicate(GetAllPhysicTables(), new EnumerableQuery<T>((Expression<Func<T, bool>>)tableRouteConfig.GetPredicate()), false);
|
||||
object shardingKeyValue = null;
|
||||
if (tableRouteConfig.UseValue())
|
||||
shardingKeyValue = tableRouteConfig.GetShardingKeyValue();
|
||||
|
@ -66,20 +84,18 @@ namespace ShardingCore.Core.VirtualTables
|
|||
if (tableRouteConfig.UseEntity())
|
||||
shardingKeyValue = tableRouteConfig.GetShardingEntity().GetPropertyValue(ShardingConfig.ShardingField);
|
||||
|
||||
if (shardingKeyValue != null)
|
||||
{
|
||||
var routeWithValue = route.RouteWithValue(GetAllPhysicTables(), shardingKeyValue);
|
||||
return new List<IPhysicTable>(1) {routeWithValue};
|
||||
}
|
||||
|
||||
throw new ShardingCoreException(" route entity queryable or sharding key value is null ");
|
||||
if (shardingKeyValue == null)
|
||||
throw new ShardingCoreException(" route entity queryable or sharding key value is null ");
|
||||
var routeWithValue = route.RouteWithValue(GetAllPhysicTables(), shardingKeyValue);
|
||||
return new List<IPhysicTable>(1) { routeWithValue };
|
||||
}
|
||||
|
||||
|
||||
public void AddPhysicTable(IPhysicTable physicTable)
|
||||
public bool AddPhysicTable(IPhysicTable physicTable)
|
||||
{
|
||||
if (GetAllPhysicTables().All(o => o.Tail != physicTable.Tail))
|
||||
_physicTables.TryAdd(physicTable,null);
|
||||
if (physicTable.EntityType != EntityType)
|
||||
throw new InvalidOperationException($"virtual table entity type :[{EntityType.FullName}] physic table entity type:[{physicTable.EntityType.FullName}]");
|
||||
return _physicTables.TryAdd(physicTable, null);
|
||||
}
|
||||
|
||||
public void SetOriginalTableName(string originalTableName)
|
|
@ -19,13 +19,13 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <summary>
|
||||
/// 同一个数据库下的虚拟表管理者
|
||||
/// </summary>
|
||||
public class OneDbVirtualTableManager : IVirtualTableManager
|
||||
public class DefaultVirtualTableManager : IVirtualTableManager
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
//{sharidngDbContextType:{entityType,virtualTableType}}
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<Type, IVirtualTable>> _shardingVirtualTables = new ConcurrentDictionary<Type, ConcurrentDictionary<Type, IVirtualTable>>();
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, IVirtualTable>> _shardingOriginalTaleVirtualTales = new ConcurrentDictionary<Type, ConcurrentDictionary<string, IVirtualTable>>();
|
||||
public OneDbVirtualTableManager(IServiceProvider serviceProvider)
|
||||
public DefaultVirtualTableManager(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
//var shardingEntities = AssemblyHelper.CurrentDomain.GetAssemblies().SelectMany(o => o.GetTypes())
|
||||
|
@ -42,31 +42,31 @@ namespace ShardingCore.Core.VirtualTables
|
|||
//}
|
||||
}
|
||||
|
||||
private void CheckShardingDbContextType(Type shardingDbContextType)
|
||||
private void CheckShardingDbContextType(Type shardingDbContextType, string dsname)
|
||||
{
|
||||
if (!shardingDbContextType.IsShardingDbContext())
|
||||
throw new ShardingCoreException(
|
||||
$"{shardingDbContextType.FullName} must impl {nameof(IShardingDbContext)}");
|
||||
}
|
||||
|
||||
private void CheckShardingTableEntityType(Type shardingEntityType)
|
||||
private void CheckShardingTableEntityType(string dsname, Type shardingEntityType)
|
||||
{
|
||||
if (!shardingEntityType.IsShardingTable())
|
||||
throw new ShardingCoreException(
|
||||
$"{shardingEntityType.FullName} must impl {nameof(IShardingTable)}");
|
||||
}
|
||||
private string CreateShardingEntityTypeKey(Type shardingDbContextType, Type entityType)
|
||||
private string CreateShardingEntityTypeKey(Type shardingDbContextType, string dsname, Type entityType)
|
||||
{
|
||||
return $"{shardingDbContextType.FullName}{entityType.FullName}";
|
||||
}
|
||||
private string CreateShardingTableNameKey(Type shardingDbContextType, string originalTableName)
|
||||
private string CreateShardingTableNameKey(Type shardingDbContextType, string dsname, string originalTableName)
|
||||
{
|
||||
return $"{shardingDbContextType.FullName}{originalTableName}";
|
||||
}
|
||||
|
||||
public void AddVirtualTable(Type shardingDbContextType, IVirtualTable virtualTable)
|
||||
public void AddVirtualTable(Type shardingDbContextType, string dsname, IVirtualTable virtualTable)
|
||||
{
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
CheckShardingDbContextType(shardingDbContextType, dsname);
|
||||
|
||||
var innerShardingVirtualTables = _shardingVirtualTables.GetOrAdd(shardingDbContextType,
|
||||
key => new ConcurrentDictionary<Type, IVirtualTable>());
|
||||
|
@ -84,12 +84,12 @@ namespace ShardingCore.Core.VirtualTables
|
|||
}
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable(Type shardingDbContextType, Type shardingEntityType)
|
||||
public IVirtualTable GetVirtualTable(Type shardingDbContextType, string dsname, Type shardingEntityType)
|
||||
{
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
CheckShardingTableEntityType(shardingEntityType);
|
||||
CheckShardingDbContextType(shardingDbContextType,dsname);
|
||||
CheckShardingTableEntityType(dsname,shardingEntityType);
|
||||
|
||||
var shardingKey = CreateShardingEntityTypeKey(shardingDbContextType, shardingEntityType);
|
||||
var shardingKey = CreateShardingEntityTypeKey(shardingDbContextType, dsname, shardingEntityType);
|
||||
if(!_shardingVirtualTables.TryGetValue(shardingDbContextType,out var innerShardingVirtualTables) || innerShardingVirtualTables.IsEmpty())
|
||||
throw new ShardingVirtualTableNotFoundException(shardingDbContextType.FullName);
|
||||
|
||||
|
@ -99,14 +99,14 @@ namespace ShardingCore.Core.VirtualTables
|
|||
}
|
||||
|
||||
|
||||
public IVirtualTable<T> GetVirtualTable<TDbContext, T>() where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext
|
||||
public IVirtualTable<T> GetVirtualTable<TDbContext, T>(string dsname) where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return (IVirtualTable<T>)GetVirtualTable(typeof(TDbContext), typeof(T));
|
||||
return (IVirtualTable<T>)GetVirtualTable(typeof(TDbContext), dsname, typeof(T));
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable(Type shardingDbContextType, string originalTableName)
|
||||
public IVirtualTable GetVirtualTable(Type shardingDbContextType, string dsname, string originalTableName)
|
||||
{
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
CheckShardingDbContextType(shardingDbContextType, dsname);
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(shardingDbContextType, out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
throw new ShardingVirtualTableNotFoundException(shardingDbContextType.FullName);
|
||||
if(!innerShardingOriginalTableVirtualTables.TryGetValue(originalTableName,out var virtualTable)|| virtualTable==null)
|
||||
|
@ -114,14 +114,14 @@ namespace ShardingCore.Core.VirtualTables
|
|||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable GetVirtualTable<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
public IVirtualTable GetVirtualTable<TDbContext>(string dsname, string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return GetVirtualTable(typeof(TDbContext), originalTableName);
|
||||
return GetVirtualTable(typeof(TDbContext), dsname,originalTableName);
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string originalTableName)
|
||||
public IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string dsname, string originalTableName)
|
||||
{
|
||||
CheckShardingDbContextType(shardingDbContextType);
|
||||
CheckShardingDbContextType(shardingDbContextType,dsname);
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(shardingDbContextType,
|
||||
out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
return null;
|
||||
|
@ -130,12 +130,13 @@ namespace ShardingCore.Core.VirtualTables
|
|||
return virtualTable;
|
||||
}
|
||||
|
||||
public IVirtualTable TryGetVirtualTablee<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
public IVirtualTable TryGetVirtualTablee<TDbContext>(string dsname, string originalTableName) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return TryGetVirtualTable(typeof(TDbContext), originalTableName);
|
||||
return TryGetVirtualTable(typeof(TDbContext), dsname, originalTableName);
|
||||
}
|
||||
|
||||
public List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType)
|
||||
|
||||
public List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType, string dsname)
|
||||
{
|
||||
if (!_shardingOriginalTaleVirtualTales.TryGetValue(shardingDbContextType,
|
||||
out var innerShardingOriginalTableVirtualTables) || innerShardingOriginalTableVirtualTables.IsEmpty())
|
||||
|
@ -144,31 +145,32 @@ namespace ShardingCore.Core.VirtualTables
|
|||
return innerShardingOriginalTableVirtualTables.Values.ToList();
|
||||
}
|
||||
|
||||
public List<IVirtualTable> GetAllVirtualTables<TDbContext>() where TDbContext : DbContext, IShardingDbContext
|
||||
public List<IVirtualTable> GetAllVirtualTables<TDbContext>(string dsname) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return GetAllVirtualTables(typeof(TDbContext));
|
||||
return GetAllVirtualTables(typeof(TDbContext),dsname);
|
||||
}
|
||||
|
||||
public void AddPhysicTable(Type shardingDbContextType, IVirtualTable virtualTable, IPhysicTable physicTable)
|
||||
public void AddPhysicTable(Type shardingDbContextType, string dsname, IVirtualTable virtualTable, IPhysicTable physicTable)
|
||||
{
|
||||
AddPhysicTable(shardingDbContextType, virtualTable.EntityType, physicTable);
|
||||
AddPhysicTable(shardingDbContextType, dsname, virtualTable.EntityType, physicTable);
|
||||
}
|
||||
|
||||
public void AddPhysicTable<TDbContext>(IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
public void AddPhysicTable<TDbContext>(string dsname, IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
AddPhysicTable(typeof(TDbContext), virtualTable.EntityType, physicTable);
|
||||
AddPhysicTable(typeof(TDbContext), dsname, virtualTable.EntityType, physicTable);
|
||||
}
|
||||
|
||||
|
||||
public void AddPhysicTable(Type shardingDbContextType, Type shardingEntityType, IPhysicTable physicTable)
|
||||
public void AddPhysicTable(Type shardingDbContextType, string dsname, Type shardingEntityType, IPhysicTable physicTable)
|
||||
{
|
||||
var virtualTable = GetVirtualTable(shardingDbContextType, shardingEntityType);
|
||||
var virtualTable = GetVirtualTable(shardingDbContextType, dsname,shardingEntityType);
|
||||
virtualTable.AddPhysicTable(physicTable);
|
||||
}
|
||||
|
||||
public void AddPhysicTable<TDbContext>(Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
|
||||
public void AddPhysicTable<TDbContext>(string dsname, Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualTable = GetVirtualTable(typeof(TDbContext), shardingEntityType);
|
||||
var virtualTable = GetVirtualTable(typeof(TDbContext), dsname,shardingEntityType);
|
||||
virtualTable.AddPhysicTable(physicTable);
|
||||
}
|
||||
|
|
@ -1,20 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Sharding.PaginationConfigurations;
|
||||
|
||||
namespace ShardingCore.Core.VirtualTables
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 18 December 2020 14:06:31
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:虚拟表在系统里面被映射为ef-core的表
|
||||
* @Date: Friday, 18 December 2020 14:06:31
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 虚拟表
|
||||
/// </summary>
|
||||
public interface IVirtualTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据源名称
|
||||
/// </summary>
|
||||
string DSName { get; }
|
||||
/// <summary>
|
||||
/// 分表的类型
|
||||
/// </summary>
|
||||
|
@ -30,7 +37,11 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <summary>
|
||||
/// 是否启用分页配置
|
||||
/// </summary>
|
||||
bool EnablePagination { get; }
|
||||
bool EnablePagination { get; }
|
||||
/// <summary>
|
||||
/// 所属虚拟数据库
|
||||
/// </summary>
|
||||
IVirtualDataSource VirtualDataSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的物理表
|
||||
|
@ -43,13 +54,14 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// </summary>
|
||||
/// <param name="tableRouteConfig"></param>
|
||||
/// <returns></returns>
|
||||
List<IPhysicTable> RouteTo(TableRouteConfig tableRouteConfig);
|
||||
List<IPhysicTable> RouteTo(ShardingTableRouteConfig tableRouteConfig);
|
||||
|
||||
/// <summary>
|
||||
/// 添加物理表 add physic table
|
||||
/// </summary>
|
||||
/// <param name="physicTable"></param>
|
||||
void AddPhysicTable(IPhysicTable physicTable);
|
||||
/// <returns>添加成功</returns>
|
||||
bool AddPhysicTable(IPhysicTable physicTable);
|
||||
|
||||
/// <summary>
|
||||
/// 设置原始表名 get original table name when app start
|
||||
|
@ -75,7 +87,7 @@ namespace ShardingCore.Core.VirtualTables
|
|||
List<string> GetTaleAllTails();
|
||||
}
|
||||
|
||||
public interface IVirtualTable<T> : IVirtualTable where T : class, IShardingTable
|
||||
public interface IVirtualTable<T> : IVirtualTable where T : class
|
||||
{
|
||||
new IVirtualTableRoute<T> GetVirtualRoute();
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace ShardingCore.Core.VirtualTables
|
|||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Description: 用于管理虚拟表并且提供简单的操作方法api
|
||||
* @Date: Friday, 18 December 2020 14:10:03
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
|
@ -21,8 +21,9 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// 添加虚拟表应用启动时 add virtual table when app start
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="dsname">分表的dbcontext类型</param>
|
||||
/// <param name="virtualTable">虚拟表</param>
|
||||
void AddVirtualTable(Type shardingDbContextType,IVirtualTable virtualTable);
|
||||
void AddVirtualTable(Type shardingDbContextType,string dsname,IVirtualTable virtualTable);
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
|
@ -30,14 +31,14 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(Type shardingDbContextType, Type shardingEntityType);
|
||||
IVirtualTable GetVirtualTable(Type shardingDbContextType, string dsname, Type shardingEntityType);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by sharding entity type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IVirtualTable<T> GetVirtualTable<TDbContext,T>() where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext;
|
||||
IVirtualTable<T> GetVirtualTable<TDbContext,T>(string dsname) where T : class, IShardingTable where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
/// <summary>
|
||||
/// 获取虚拟表 get virtual table by original table name
|
||||
|
@ -45,8 +46,8 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="originalTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable GetVirtualTable(Type shardingDbContextType, string originalTableName);
|
||||
IVirtualTable GetVirtualTable<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||
IVirtualTable GetVirtualTable(Type shardingDbContextType, string dsname, string originalTableName);
|
||||
IVirtualTable GetVirtualTable<TDbContext>(string dsname, string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取虚拟表没有返回null
|
||||
|
@ -54,16 +55,16 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="originalTableName"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string originalTableName);
|
||||
IVirtualTable TryGetVirtualTablee<TDbContext>(string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||
IVirtualTable TryGetVirtualTable(Type shardingDbContextType, string dsname, string originalTableName);
|
||||
IVirtualTable TryGetVirtualTablee<TDbContext>(string dsname, string originalTableName) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有的虚拟表 get all virtual table
|
||||
/// </summary>
|
||||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <returns></returns>
|
||||
List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType);
|
||||
List<IVirtualTable> GetAllVirtualTables<TDbContext>() where TDbContext : DbContext, IShardingDbContext;
|
||||
List<IVirtualTable> GetAllVirtualTables(Type shardingDbContextType, string dsname);
|
||||
List<IVirtualTable> GetAllVirtualTables<TDbContext>(string dsname) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -72,8 +73,8 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="virtualTable"></param>
|
||||
/// <param name="physicTable"></param>
|
||||
void AddPhysicTable(Type shardingDbContextType,IVirtualTable virtualTable, IPhysicTable physicTable);
|
||||
void AddPhysicTable<TDbContext>(IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext;
|
||||
void AddPhysicTable(Type shardingDbContextType,string dsname, IVirtualTable virtualTable, IPhysicTable physicTable);
|
||||
void AddPhysicTable<TDbContext>(string dsname, IVirtualTable virtualTable, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
@ -82,8 +83,8 @@ namespace ShardingCore.Core.VirtualTables
|
|||
/// <param name="shardingDbContextType">分表的dbcontext类型</param>
|
||||
/// <param name="shardingEntityType"></param>
|
||||
/// <param name="physicTable"></param>
|
||||
void AddPhysicTable(Type shardingDbContextType,Type shardingEntityType, IPhysicTable physicTable);
|
||||
void AddPhysicTable<TDbContext>(Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext;
|
||||
void AddPhysicTable(Type shardingDbContextType, string dsname, Type shardingEntityType, IPhysicTable physicTable);
|
||||
void AddPhysicTable<TDbContext>(string dsname, Type shardingEntityType, IPhysicTable physicTable) where TDbContext : DbContext, IShardingDbContext;
|
||||
|
||||
///// <summary>
|
||||
///// 添加物理表 add physic table
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Friday, 05 February 2021 13:03:58
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IVirtualDataSourceRoute
|
||||
{
|
||||
Type EntityType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 根据查询条件路由返回物理数据源
|
||||
/// </summary>
|
||||
/// <param name="allPhysicDataSources"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
List<IPhysicDataSource> RouteWithWhere(ISet<IPhysicDataSource> allPhysicDataSources,IQueryable queryable);
|
||||
|
||||
/// <summary>
|
||||
/// 根据值进行路由
|
||||
/// </summary>
|
||||
/// <param name="allPhysicDataSources"></param>
|
||||
/// <param name="shardingKeyValue"></param>
|
||||
/// <returns></returns>
|
||||
IPhysicDataSource RouteWithValue(ISet<IPhysicDataSource> allPhysicDataSources, object shardingKeyValue);
|
||||
|
||||
}
|
||||
|
||||
public interface IVirtualDataSourceRoute<T> : IVirtualDataSourceRoute where T : class
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 12:58:34
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DataSourceRouteResult
|
||||
{
|
||||
public DataSourceRouteResult(ISet<IPhysicDataSource> intersectDataSources)
|
||||
{
|
||||
IntersectDataSources = intersectDataSources;
|
||||
}
|
||||
/// <summary>
|
||||
/// 交集
|
||||
/// </summary>
|
||||
public ISet<IPhysicDataSource> IntersectDataSources { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 12:57:43
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 分库路由上下文
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class DataSourceRouteRuleContext<T>
|
||||
{
|
||||
public ISet<Type> QueryEntities { get; }
|
||||
public DataSourceRouteRuleContext(IQueryable<T> queryable)
|
||||
{
|
||||
Queryable = queryable;
|
||||
QueryEntities = queryable.ParseQueryableRoute();
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询条件
|
||||
/// </summary>
|
||||
public IQueryable<T> Queryable { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 13:00:12
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class DataSourceRouteRuleEngine : IDataSourceRouteRuleEngine
|
||||
{
|
||||
private readonly IVirtualDataSourceManager _virtualDataSourceManager;
|
||||
|
||||
public DataSourceRouteRuleEngine(IVirtualDataSourceManager virtualDataSourceManager)
|
||||
{
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
}
|
||||
|
||||
public DataSourceRouteResult Route<T, TShardingDbContext>(DataSourceRouteRuleContext<T> routeRuleContext) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return this.Route<T>(typeof(TShardingDbContext), routeRuleContext);
|
||||
}
|
||||
|
||||
public DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> routeRuleContext)
|
||||
{
|
||||
if (!shardingDbContextType.IsShardingDataSource())
|
||||
throw new InvalidOperationException($"{shardingDbContextType} must impl {nameof(IShardingDbContext)}");
|
||||
var dataSourceMaps = new Dictionary<Type, ISet<IPhysicDataSource>>();
|
||||
var notShardingDataSourceEntityType = routeRuleContext.QueryEntities.FirstOrDefault(o => !o.IsShardingDataSource());
|
||||
//存在不分表的
|
||||
if (notShardingDataSourceEntityType != null)
|
||||
dataSourceMaps.Add(notShardingDataSourceEntityType, new HashSet<IPhysicDataSource>() { _virtualDataSourceManager.GetDefaultDataSource(shardingDbContextType) });
|
||||
|
||||
|
||||
var queryEntities = routeRuleContext.QueryEntities.Where(o => o.IsShardingDataSource()).ToList();
|
||||
if (queryEntities.Count > 1)
|
||||
throw new ShardingCoreNotSupportedException($"{routeRuleContext.Queryable.ShardingPrint()}");
|
||||
foreach (var queryEntity in queryEntities)
|
||||
{
|
||||
var virtualDataSource = _virtualDataSourceManager.GetVirtualDataSource(queryEntity);
|
||||
var dataSourceConfigs = virtualDataSource.RouteTo(new ShardingDataSourceRouteConfig(routeRuleContext.Queryable));
|
||||
if (!dataSourceMaps.ContainsKey(queryEntity))
|
||||
{
|
||||
dataSourceMaps.Add(queryEntity, dataSourceConfigs.ToHashSet());
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var shardingDataSource in dataSourceConfigs)
|
||||
{
|
||||
dataSourceMaps[queryEntity].Add(shardingDataSource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dataSourceMaps.IsEmpty())
|
||||
throw new ShardingDataSourceRouteNotMatchException(
|
||||
$"{routeRuleContext.Queryable.ShardingPrint()}");
|
||||
if (dataSourceMaps.Count == 1)
|
||||
return new DataSourceRouteResult(dataSourceMaps.First().Value);
|
||||
var intersect = dataSourceMaps.Select(o => o.Value).Aggregate((p, n) => p.Intersect(n).ToHashSet());
|
||||
return new DataSourceRouteResult(intersect);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 14:30:57
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 分库路由引擎工程
|
||||
/// </summary>
|
||||
public class DataSourceRouteRuleEngineFactory: IDataSourceRouteRuleEngineFactory
|
||||
{
|
||||
private readonly IDataSourceRouteRuleEngine _dataSourceRouteRuleEngine;
|
||||
/// <summary>
|
||||
/// ctor
|
||||
/// </summary>
|
||||
/// <param name="dataSourceRouteRuleEngine"></param>
|
||||
public DataSourceRouteRuleEngineFactory(IDataSourceRouteRuleEngine dataSourceRouteRuleEngine)
|
||||
{
|
||||
_dataSourceRouteRuleEngine = dataSourceRouteRuleEngine;
|
||||
}
|
||||
/// <summary>
|
||||
/// 通过表达式创建分库路由上下文
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
public DataSourceRouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable)
|
||||
{
|
||||
return new DataSourceRouteRuleContext<T>(queryable);
|
||||
}
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="shardingDbContextType"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
public DataSourceRouteResult Route<T>(Type shardingDbContextType, IQueryable<T> queryable)
|
||||
{
|
||||
var ruleContext = CreateContext<T>(queryable);
|
||||
return _dataSourceRouteRuleEngine.Route(shardingDbContextType,ruleContext);
|
||||
}
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="shardingDbContextType"></param>
|
||||
/// <param name="ruleContext"></param>
|
||||
/// <returns></returns>
|
||||
public DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> ruleContext)
|
||||
{
|
||||
return _dataSourceRouteRuleEngine.Route(shardingDbContextType, ruleContext);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 12:50:31
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IDataSourceRouteRuleEngine
|
||||
{
|
||||
DataSourceRouteResult Route<T,TShardingDbContext>(DataSourceRouteRuleContext<T> routeRuleContext) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> routeRuleContext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 12:59:53
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IDataSourceRouteRuleEngineFactory
|
||||
{
|
||||
DataSourceRouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
|
||||
DataSourceRouteResult Route<T>(Type shardingDbContextType, IQueryable<T> queryable);
|
||||
DataSourceRouteResult Route<T>(Type shardingDbContextType, DataSourceRouteRuleContext<T> ruleContext);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
using ShardingCore.Core.VirtualRoutes.RouteTails;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
|
@ -19,13 +19,13 @@ namespace ShardingCore.Core.VirtualRoutes
|
|||
return new SingleQueryRouteTail(tail);
|
||||
}
|
||||
|
||||
public IRouteTail Create(RouteResult routeResult)
|
||||
public IRouteTail Create(TableRouteResult tableRouteResult)
|
||||
{
|
||||
if (routeResult == null || routeResult.ReplaceTables.IsEmpty())
|
||||
if (tableRouteResult == null || tableRouteResult.ReplaceTables.IsEmpty())
|
||||
return new SingleQueryRouteTail(string.Empty);
|
||||
if (routeResult.ReplaceTables.Count == 1)
|
||||
return new SingleQueryRouteTail(routeResult);
|
||||
return new MultiQueryRouteTail(routeResult);
|
||||
if (tableRouteResult.ReplaceTables.Count == 1)
|
||||
return new SingleQueryRouteTail(tableRouteResult);
|
||||
return new MultiQueryRouteTail(tableRouteResult);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Saturday, 06 February 2021 11:28:33
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingDataSourceRouteConfig
|
||||
{
|
||||
|
||||
private readonly IQueryable _queryable;
|
||||
private readonly IShardingDataSource _shardingDataSource;
|
||||
private readonly object _shardingKeyValue;
|
||||
private readonly Expression _predicate;
|
||||
|
||||
|
||||
public ShardingDataSourceRouteConfig(IQueryable queryable=null,IShardingDataSource shardingDataSource=null,object shardingKeyValue=null,Expression predicate=null)
|
||||
{
|
||||
_queryable = queryable;
|
||||
_shardingDataSource = shardingDataSource;
|
||||
_shardingKeyValue = shardingKeyValue;
|
||||
_predicate = predicate;
|
||||
}
|
||||
|
||||
public IQueryable GetQueryable()
|
||||
{
|
||||
return _queryable;
|
||||
}
|
||||
public object GetShardingKeyValue()
|
||||
{
|
||||
return _shardingKeyValue;
|
||||
}
|
||||
|
||||
public IShardingDataSource GetShardingDataSource()
|
||||
{
|
||||
return _shardingDataSource;
|
||||
}
|
||||
|
||||
public Expression GetPredicate()
|
||||
{
|
||||
return _predicate;
|
||||
}
|
||||
|
||||
public bool UseQueryable()
|
||||
{
|
||||
return _queryable != null;
|
||||
}
|
||||
|
||||
public bool UseValue()
|
||||
{
|
||||
return _shardingKeyValue != null;
|
||||
}
|
||||
|
||||
public bool UseEntity()
|
||||
{
|
||||
return _shardingDataSource != null;
|
||||
}
|
||||
|
||||
public bool UsePredicate()
|
||||
{
|
||||
return _predicate != null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
|
|||
List<string> GetAllTails();
|
||||
}
|
||||
|
||||
public interface IVirtualTableRoute<T> : IVirtualTableRoute where T : class, IShardingTable
|
||||
public interface IVirtualTableRoute<T> : IVirtualTableRoute where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回null就是表示不开启分页配置
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
|
@ -1,4 +1,4 @@
|
|||
namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
|
@ -1,6 +1,6 @@
|
|||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
|
@ -11,6 +11,6 @@ namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
|
|||
public interface IRouteTailFactory
|
||||
{
|
||||
IRouteTail Create(string tail);
|
||||
IRouteTail Create(RouteResult routeResult);
|
||||
IRouteTail Create(TableRouteResult tableRouteResult);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
|
@ -1,11 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.RouteTails
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
|
@ -16,16 +16,16 @@ namespace ShardingCore.Core.VirtualRoutes.RouteTails
|
|||
public class MultiQueryRouteTail:IMultiQueryRouteTail
|
||||
{
|
||||
private const string RANDOM_MODEL_CACHE_KEY = "RANDOM_MODEL_CACHE_KEY";
|
||||
private readonly RouteResult _routeResult;
|
||||
private readonly TableRouteResult _tableRouteResult;
|
||||
private readonly string _modelCacheKey;
|
||||
private readonly ISet<Type> _entityTypes;
|
||||
|
||||
public MultiQueryRouteTail(RouteResult routeResult)
|
||||
public MultiQueryRouteTail(TableRouteResult tableRouteResult)
|
||||
{
|
||||
if (routeResult.ReplaceTables.IsEmpty() || routeResult.ReplaceTables.Count <= 1) throw new ArgumentException("route result replace tables must greater than 1");
|
||||
_routeResult = routeResult;
|
||||
if (tableRouteResult.ReplaceTables.IsEmpty() || tableRouteResult.ReplaceTables.Count <= 1) throw new ArgumentException("route result replace tables must greater than 1");
|
||||
_tableRouteResult = tableRouteResult;
|
||||
_modelCacheKey = RANDOM_MODEL_CACHE_KEY+Guid.NewGuid().ToString("n");
|
||||
_entityTypes = routeResult.ReplaceTables.Select(o=>o.EntityType).ToHashSet();
|
||||
_entityTypes = tableRouteResult.ReplaceTables.Select(o=>o.EntityType).ToHashSet();
|
||||
}
|
||||
public string GetRouteTailIdentity()
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace ShardingCore.Core.VirtualRoutes.RouteTails
|
|||
|
||||
public string GetEntityTail(Type entityType)
|
||||
{
|
||||
return _routeResult.ReplaceTables.Single(o => o.EntityType == entityType).Tail;
|
||||
return _tableRouteResult.ReplaceTables.Single(o => o.EntityType == entityType).Tail;
|
||||
}
|
||||
|
||||
public ISet<Type> GetEntityTypes()
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Extensions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.RouteTails
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
|
@ -14,15 +14,15 @@ namespace ShardingCore.Core.VirtualRoutes.RouteTails
|
|||
*/
|
||||
public class SingleQueryRouteTail:ISingleQueryRouteTail
|
||||
{
|
||||
private readonly RouteResult _routeResult;
|
||||
private readonly TableRouteResult _tableRouteResult;
|
||||
private readonly string _tail;
|
||||
private readonly string _modelCacheKey;
|
||||
|
||||
public SingleQueryRouteTail(RouteResult routeResult)
|
||||
public SingleQueryRouteTail(TableRouteResult tableRouteResult)
|
||||
{
|
||||
if (routeResult.ReplaceTables.IsEmpty() || routeResult.ReplaceTables.Count > 1) throw new ArgumentException("route result replace tables must 1");
|
||||
_routeResult = routeResult;
|
||||
_tail= _routeResult.ReplaceTables.First().Tail;
|
||||
if (tableRouteResult.ReplaceTables.IsEmpty() || tableRouteResult.ReplaceTables.Count > 1) throw new ArgumentException("route result replace tables must 1");
|
||||
_tableRouteResult = tableRouteResult;
|
||||
_tail= _tableRouteResult.ReplaceTables.First().Tail;
|
||||
_modelCacheKey = _tail.FormatRouteTail2ModelCacheKey();
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 10:25:22
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IRouteRuleEngine
|
||||
{
|
||||
IEnumerable<RouteResult> Route<T,TShardingDbContext>(RouteRuleContext<T> routeRuleContext) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
IEnumerable<RouteResult> Route<T>(Type shardingDbContextType,RouteRuleContext<T> routeRuleContext);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 13:30:28
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IRoutingRuleEngineFactory
|
||||
{
|
||||
IRouteRuleEngine CreateEngine();
|
||||
RouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable);
|
||||
IEnumerable<RouteResult> Route<T,TShardingDbContext>(IQueryable<T> queryable) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
IEnumerable<RouteResult> Route<T, TShardingDbContext>(RouteRuleContext<T> ruleContext) where TShardingDbContext : DbContext, IShardingDbContext;
|
||||
IEnumerable<RouteResult> Route<T>(Type shardingDbContextType,IQueryable<T> queryable);
|
||||
IEnumerable<RouteResult> Route<T>(Type shardingDbContextType,RouteRuleContext<T> ruleContext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 10:25:22
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface ITableRouteRuleEngine
|
||||
{
|
||||
IEnumerable<TableRouteResult> Route<T,TShardingDbContext>(TableRouteRuleContext<T> tableRouteRuleContext) where TShardingDbContext:DbContext,IShardingDbContext;
|
||||
IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType,TableRouteRuleContext<T> tableRouteRuleContext);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 13:30:28
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface ITableRouteRuleEngineFactory
|
||||
{
|
||||
TableRouteRuleContext<T> CreateContext<T>(string dsname, IQueryable<T> queryable);
|
||||
IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, string dsname, IQueryable<T> queryable);
|
||||
IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, TableRouteRuleContext<T> ruleContext);
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 10:54:52
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class RouteRuleContext<T>
|
||||
{
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
|
||||
public RouteRuleContext(IQueryable<T> queryable, IVirtualTableManager virtualTableManager)
|
||||
{
|
||||
Queryable = queryable;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
|
||||
public IQueryable<T> Queryable { get; }
|
||||
|
||||
///// <summary>
|
||||
/////
|
||||
///// </summary>
|
||||
//public readonly Dictionary<IVirtualTable, Expression> ManualPredicate = new Dictionary<IVirtualTable, Expression>();
|
||||
//public readonly Dictionary<IVirtualTable, ISet<string>> ManualTails = new Dictionary<IVirtualTable, ISet<string>>();
|
||||
|
||||
//public bool AutoParseRoute = true;
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 启用自动路由
|
||||
///// </summary>
|
||||
//public void EnableAutoRouteParse()
|
||||
//{
|
||||
// AutoParseRoute = true;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 禁用自动路由
|
||||
///// </summary>
|
||||
//public void DisableAutoRouteParse()
|
||||
//{
|
||||
// AutoParseRoute = false;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// 添加手动路由
|
||||
///// </summary>
|
||||
///// <param name="predicate"></param>
|
||||
///// <typeparam name="TShardingEntity"></typeparam>
|
||||
//public void AddRoute<TShardingEntity>(Expression<Func<TShardingEntity, bool>> predicate) where TShardingEntity : class, IShardingTable
|
||||
//{
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable<TShardingEntity>();
|
||||
// if (!ManualPredicate.ContainsKey(virtualTable))
|
||||
// {
|
||||
// ShardingCore.Extensions.ExpressionExtension.And((Expression<Func<TShardingEntity, bool>>) ManualPredicate[virtualTable], predicate);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ManualPredicate.Add(virtualTable, predicate);
|
||||
// }
|
||||
//}
|
||||
//public void AddRoute(Type shardingEntityType,string tail)
|
||||
//{
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntityType);
|
||||
// AddRoute(virtualTable, tail);
|
||||
//}
|
||||
|
||||
//public void AddRoute<TShardingEntity>(string tail) where TShardingEntity : class, IShardingTable
|
||||
//{
|
||||
// AddRoute(typeof(TShardingEntity), tail);
|
||||
//}
|
||||
|
||||
//public void AddRoute(IVirtualTable virtualTable, string tail)
|
||||
//{
|
||||
// if (ManualTails.ContainsKey(virtualTable))
|
||||
// {
|
||||
// var tails = ManualTails[virtualTable];
|
||||
// if (!tails.Contains(tail))
|
||||
// {
|
||||
// tails.Add(tail);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ManualTails.Add(virtualTable, new HashSet<string>()
|
||||
// {
|
||||
// tail
|
||||
// });
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 13:31:06
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class RoutingRuleEngineFactory : IRoutingRuleEngineFactory
|
||||
{
|
||||
private readonly IRouteRuleEngine _routeRuleEngine;
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
|
||||
public RoutingRuleEngineFactory(IRouteRuleEngine routeRuleEngine, IVirtualTableManager virtualTableManager)
|
||||
{
|
||||
_routeRuleEngine = routeRuleEngine;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
|
||||
public IRouteRuleEngine CreateEngine()
|
||||
{
|
||||
return _routeRuleEngine;
|
||||
}
|
||||
|
||||
public RouteRuleContext<T> CreateContext<T>(IQueryable<T> queryable)
|
||||
{
|
||||
return new RouteRuleContext<T>(queryable, _virtualTableManager);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T, TShardingDbContext>(IQueryable<T> queryable) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var engine = CreateEngine();
|
||||
var ruleContext = CreateContext<T>(queryable);
|
||||
return engine.Route<T,TShardingDbContext>(ruleContext);
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T, TShardingDbContext>(RouteRuleContext<T> ruleContext) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var engine = CreateEngine();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,16 +14,16 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
* @Date: Thursday, 28 January 2021 10:18:09
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class RouteResult
|
||||
public class TableRouteResult
|
||||
{
|
||||
public RouteResult(IEnumerable<IPhysicTable> replaceTables)
|
||||
public TableRouteResult(IEnumerable<IPhysicTable> replaceTables)
|
||||
{
|
||||
ReplaceTables = replaceTables.ToHashSet();
|
||||
}
|
||||
|
||||
public ISet<IPhysicTable> ReplaceTables { get; }
|
||||
|
||||
protected bool Equals(RouteResult other)
|
||||
protected bool Equals(TableRouteResult other)
|
||||
{
|
||||
return Equals(ReplaceTables, other.ReplaceTables);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((RouteResult) obj);
|
||||
return Equals((TableRouteResult) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
|
@ -0,0 +1,27 @@
|
|||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 10:54:52
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class TableRouteRuleContext<T>
|
||||
{
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
|
||||
public TableRouteRuleContext(string dsname, IQueryable<T> queryable, IVirtualTableManager virtualTableManager)
|
||||
{
|
||||
Dsname = dsname;
|
||||
Queryable = queryable;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
|
||||
public string Dsname { get; }
|
||||
public IQueryable<T> Queryable { get; }
|
||||
|
||||
}
|
||||
}
|
|
@ -20,20 +20,20 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
* @Date: Thursday, 28 January 2021 10:51:59
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class QueryRouteRuleEngines:IRouteRuleEngine
|
||||
public class TableRouteRuleEngines:ITableRouteRuleEngine
|
||||
{
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
|
||||
public QueryRouteRuleEngines(IVirtualTableManager virtualTableManager)
|
||||
public TableRouteRuleEngines(IVirtualTableManager virtualTableManager)
|
||||
{
|
||||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T, TShardingDbContext>(RouteRuleContext<T> routeRuleContext) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
public IEnumerable<TableRouteResult> Route<T, TShardingDbContext>(TableRouteRuleContext<T> tableRouteRuleContext) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return Route(typeof(TShardingDbContext), routeRuleContext);
|
||||
return Route(typeof(TShardingDbContext), tableRouteRuleContext);
|
||||
////先添加手动路由到当前上下文,之后将不再手动路由里面的自动路由添加到当前上下文
|
||||
//foreach (var kv in routeRuleContext.ManualTails)
|
||||
//foreach (var kv in tableRouteRuleContext.ManualTails)
|
||||
//{
|
||||
// var virtualTable = kv.Key;
|
||||
// var addTails = kv.Value;
|
||||
|
@ -50,7 +50,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
// }
|
||||
// }
|
||||
//}
|
||||
//foreach (var kv in routeRuleContext.ManualPredicate)
|
||||
//foreach (var kv in tableRouteRuleContext.ManualPredicate)
|
||||
//{
|
||||
// var virtualTable = kv.Key;
|
||||
// var predicate = kv.Value;
|
||||
|
@ -68,14 +68,14 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
// }
|
||||
//}
|
||||
|
||||
//if (routeRuleContext.AutoParseRoute)
|
||||
//if (tableRouteRuleContext.AutoParseRoute)
|
||||
//{
|
||||
// var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
|
||||
// foreach (var shardingEntity in shardingEntities)
|
||||
// {
|
||||
// var virtualTable = _virtualTableManager.GetVirtualTable(shardingEntity);
|
||||
|
||||
// var physicTables = virtualTable.RouteTo(new TableRouteConfig(routeRuleContext.Queryable));
|
||||
// var physicTables = virtualTable.RouteTo(new TableRouteConfig(tableRouteRuleContext.Queryable));
|
||||
// if (!routeMaps.ContainsKey(virtualTable))
|
||||
// {
|
||||
// routeMaps.Add(virtualTable, physicTables.ToHashSet());
|
||||
|
@ -91,10 +91,10 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
//}
|
||||
}
|
||||
|
||||
public IEnumerable<RouteResult> Route<T>(Type shardingDbContextType, RouteRuleContext<T> routeRuleContext)
|
||||
public IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, TableRouteRuleContext<T> tableRouteRuleContext)
|
||||
{
|
||||
Dictionary<IVirtualTable, ISet<IPhysicTable>> routeMaps = new Dictionary<IVirtualTable, ISet<IPhysicTable>>();
|
||||
var queryEntities = routeRuleContext.Queryable.ParseQueryableRoute();
|
||||
var queryEntities = tableRouteRuleContext.Queryable.ParseQueryableRoute();
|
||||
|
||||
|
||||
var shardingEntities = queryEntities.Where(o => o.IsShardingTable());
|
||||
|
@ -102,7 +102,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
{
|
||||
var virtualTable = _virtualTableManager.GetVirtualTable(shardingDbContextType, shardingEntity);
|
||||
|
||||
var physicTables = virtualTable.RouteTo(new TableRouteConfig(routeRuleContext.Queryable));
|
||||
var physicTables = virtualTable.RouteTo(new ShardingTableRouteConfig(tableRouteRuleContext.Queryable));
|
||||
if (!routeMaps.ContainsKey(virtualTable))
|
||||
{
|
||||
routeMaps.Add(virtualTable, physicTables.ToHashSet());
|
||||
|
@ -116,7 +116,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
|||
}
|
||||
}
|
||||
|
||||
return routeMaps.Select(o => o.Value).Cartesian().Select(o => new RouteResult(o));
|
||||
return routeMaps.Select(o => o.Value).Cartesian().Select(o => new TableRouteResult(o));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 28 January 2021 13:31:06
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
/// <summary>
|
||||
/// 表路由规则引擎工厂
|
||||
/// </summary>
|
||||
public class TableRouteRuleEngineFactory : ITableRouteRuleEngineFactory
|
||||
{
|
||||
private readonly ITableRouteRuleEngine _tableRouteRuleEngine;
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
|
||||
public TableRouteRuleEngineFactory(ITableRouteRuleEngine tableRouteRuleEngine, IVirtualTableManager virtualTableManager)
|
||||
{
|
||||
_tableRouteRuleEngine = tableRouteRuleEngine;
|
||||
_virtualTableManager = virtualTableManager;
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建表路由上下文
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="dsname"></param>
|
||||
/// <param name="queryable"></param>
|
||||
/// <returns></returns>
|
||||
public TableRouteRuleContext<T> CreateContext<T>(string dsname,IQueryable<T> queryable)
|
||||
{
|
||||
return new TableRouteRuleContext<T>(dsname,queryable, _virtualTableManager);
|
||||
}
|
||||
|
||||
public IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, string dsname, IQueryable<T> queryable)
|
||||
{
|
||||
var ruleContext = CreateContext<T>(dsname,queryable);
|
||||
return _tableRouteRuleEngine.Route(shardingDbContextType,ruleContext);
|
||||
}
|
||||
|
||||
public IEnumerable<TableRouteResult> Route<T>(Type shardingDbContextType, TableRouteRuleContext<T> ruleContext)
|
||||
{
|
||||
return _tableRouteRuleEngine.Route(shardingDbContextType,ruleContext);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
|
|||
* @Date: Friday, 18 December 2020 14:15:02
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class TableRouteConfig
|
||||
public class ShardingTableRouteConfig
|
||||
{
|
||||
private readonly IQueryable _queryable;
|
||||
private readonly IShardingTable _shardingTable;
|
||||
|
@ -17,7 +17,7 @@ namespace ShardingCore.Core.VirtualRoutes.TableRoutes
|
|||
private readonly Expression _predicate;
|
||||
|
||||
|
||||
public TableRouteConfig(IQueryable queryable=null,IShardingTable shardingTable=null,object shardingKeyValue=null,Expression predicate=null)
|
||||
public ShardingTableRouteConfig(IQueryable queryable=null,IShardingTable shardingTable=null,object shardingKeyValue=null,Expression predicate=null)
|
||||
{
|
||||
_queryable = queryable;
|
||||
_shardingTable = shardingTable;
|
|
@ -18,7 +18,7 @@ using ShardingCore.Core.QueryRouteManagers.Abstractions;
|
|||
using ShardingCore.Core.ShardingPage;
|
||||
using ShardingCore.Core.ShardingPage.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
using ShardingCore.Sharding.ShardingQueryExecutors;
|
||||
|
@ -55,13 +55,8 @@ namespace ShardingCore
|
|||
Action<DbContextOptionsBuilder> shardingOptionAction = option =>
|
||||
{
|
||||
optionsAction?.Invoke(option);
|
||||
#if !EFCORE2
|
||||
option.UseSharding();
|
||||
|
||||
#endif
|
||||
#if EFCORE2
|
||||
option.UseSharding<TShardingDbContext>();
|
||||
#endif
|
||||
};
|
||||
services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
|
||||
services.AddInternalShardingCore();
|
||||
|
@ -95,13 +90,7 @@ namespace ShardingCore
|
|||
Action<IServiceProvider, DbContextOptionsBuilder> shardingOptionAction = (sp, option) =>
|
||||
{
|
||||
optionsAction?.Invoke(sp,option);
|
||||
#if !EFCORE2
|
||||
option.UseSharding();
|
||||
|
||||
#endif
|
||||
#if EFCORE2
|
||||
option.UseSharding<TShardingDbContext>();
|
||||
#endif
|
||||
};
|
||||
services.AddDbContext<TShardingDbContext>(shardingOptionAction, contextLifetime, optionsLifetime);
|
||||
services.AddInternalShardingCore();
|
||||
|
@ -161,11 +150,11 @@ namespace ShardingCore
|
|||
services.AddSingleton<IShardingDbContextFactory, ShardingDbContextFactory>();
|
||||
services.AddSingleton<IShardingTableCreator, ShardingTableCreator>();
|
||||
//分表
|
||||
services.AddSingleton<IVirtualTableManager, OneDbVirtualTableManager>();
|
||||
services.AddSingleton<IVirtualTableManager, DefaultVirtualTableManager>();
|
||||
//分表引擎工程
|
||||
services.AddSingleton<IRoutingRuleEngineFactory, RoutingRuleEngineFactory>();
|
||||
services.AddSingleton<ITableRouteRuleEngineFactory, TableRouteRuleEngineFactory>();
|
||||
//分表引擎
|
||||
services.AddSingleton<IRouteRuleEngine, QueryRouteRuleEngines>();
|
||||
services.AddSingleton<ITableRouteRuleEngine, TableRouteRuleEngines>();
|
||||
services.AddSingleton<IRouteTailFactory, RouteTailFactory>();
|
||||
services.AddSingleton<IShardingQueryExecutor, DefaultShardingQueryExecutor>();
|
||||
|
||||
|
@ -179,7 +168,6 @@ namespace ShardingCore
|
|||
services.AddSingleton<IShardingBootstrapper, ShardingBootstrapper>();
|
||||
return services;
|
||||
}
|
||||
#if !EFCORE2
|
||||
internal static DbContextOptionsBuilder UseSharding(this DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
return optionsBuilder.ReplaceService<IDbSetSource, ShardingDbSetSource>()
|
||||
|
@ -187,16 +175,6 @@ namespace ShardingCore
|
|||
.ReplaceService<IRelationalTransactionFactory, ShardingRelationalTransactionFactory>();
|
||||
}
|
||||
|
||||
#endif
|
||||
#if EFCORE2
|
||||
internal static DbContextOptionsBuilder UseSharding<TShardingDbContext>(this DbContextOptionsBuilder optionsBuilder) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
return optionsBuilder.ReplaceService<IDbSetSource, ShardingDbSetSource>()
|
||||
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>()
|
||||
.ReplaceService<IRelationalTransactionFactory, ShardingRelationalTransactionFactory<TShardingDbContext>>();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
internal static DbContextOptionsBuilder UseInnerDbContextSharding<TShardingDbContext>(this DbContextOptionsBuilder optionsBuilder) where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ShardingCore.DbContexts.Abstractions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Thursday, 18 February 2021 14:29:28
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IShardingDbSource
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
namespace ShardingCore.DbContexts.ShardingDbContexts
|
||||
{
|
||||
|
|
|
@ -12,7 +12,6 @@ namespace ShardingCore.EFCores
|
|||
* @Date: Saturday, 14 August 2021 10:17:43
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
#if !EFCORE2
|
||||
public class ShardingDbSetSource:IDbSetSource
|
||||
{
|
||||
#if EFCORE5
|
||||
|
@ -81,53 +80,5 @@ namespace ShardingCore.EFCores
|
|||
=> c => new ShardingInternalDbSet<TEntity>(c);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
|
||||
/// <summary>
|
||||
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
|
||||
/// directly from your code. This API may change or be removed in future releases.
|
||||
/// </summary>
|
||||
public class ShardingDbSetSource : IDbSetSource, IDbQuerySource
|
||||
{
|
||||
private static readonly MethodInfo _genericCreateSet
|
||||
= typeof(ShardingDbSetSource).GetTypeInfo().GetDeclaredMethod(nameof(CreateSetFactory));
|
||||
|
||||
private static readonly MethodInfo _genericCreateQuery
|
||||
= typeof(ShardingDbSetSource).GetTypeInfo().GetDeclaredMethod(nameof(CreateQueryFactory));
|
||||
|
||||
private readonly ConcurrentDictionary<Type, Func<DbContext, object>> _cache
|
||||
= new ConcurrentDictionary<Type, Func<DbContext, object>>();
|
||||
|
||||
/// <summary>
|
||||
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
|
||||
/// directly from your code. This API may change or be removed in future releases.
|
||||
/// </summary>
|
||||
public virtual object Create(DbContext context, Type type)
|
||||
=> CreateCore(context, type, _genericCreateSet);
|
||||
|
||||
/// <summary>
|
||||
/// This API supports the Entity Framework Core infrastructure and is not intended to be used
|
||||
/// directly from your code. This API may change or be removed in future releases.
|
||||
/// </summary>
|
||||
public virtual object CreateQuery(DbContext context, Type type)
|
||||
=> CreateCore(context, type, _genericCreateQuery);
|
||||
|
||||
private object CreateCore(DbContext context, Type type, MethodInfo createMethod)
|
||||
=> _cache.GetOrAdd(
|
||||
type,
|
||||
t => (Func<DbContext, object>)createMethod
|
||||
.MakeGenericMethod(t)
|
||||
.Invoke(null, null))(context);
|
||||
|
||||
private static Func<DbContext, object> CreateSetFactory<TEntity>()
|
||||
where TEntity : class
|
||||
=> c => new ShardingInternalDbSet<TEntity>(c);
|
||||
|
||||
private static Func<DbContext, DbQuery<TQuery>> CreateQueryFactory<TQuery>()
|
||||
where TQuery : class
|
||||
=> c => new ShardingInternalDbQuery<TQuery>(c);
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/8/20 17:05:36
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
#if EFCORE2
|
||||
|
||||
public class ShardingInternalDbQuery<TQuery> : InternalDbQuery<TQuery> where TQuery : class
|
||||
{
|
||||
public ShardingInternalDbQuery(DbContext context) : base(context)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -55,7 +55,6 @@ namespace ShardingCore.EFCores
|
|||
/// any release. You should only use it directly in your code with extreme caution and knowing that
|
||||
/// doing so can result in application failures when updating to a new Entity Framework Core release.
|
||||
/// </summary>
|
||||
#if !EFCORE2
|
||||
public override async ValueTask<EntityEntry<TEntity>> AddAsync(
|
||||
TEntity entity,
|
||||
CancellationToken cancellationToken = default)
|
||||
|
@ -64,15 +63,6 @@ namespace ShardingCore.EFCores
|
|||
return await genericDbContext.AddAsync(entity, cancellationToken);
|
||||
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public override async Task<EntityEntry<TEntity>> AddAsync(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var genericDbContext = ((IShardingDbContext)_context).CreateGenericDbContext(entity);
|
||||
return await genericDbContext.AddAsync(entity, cancellationToken);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Text;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DbContexts.ShardingDbContexts;
|
||||
using ShardingCore.Extensions;
|
||||
|
|
|
@ -15,9 +15,6 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
|
||||
#if EFCORE2
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
#endif
|
||||
|
||||
namespace ShardingCore.EFCores
|
||||
{
|
||||
|
@ -44,7 +41,6 @@ namespace ShardingCore.EFCores
|
|||
return _shardingQueryExecutor.Execute<TResult>(_currentContext, query);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public TResult ExecuteAsync<TResult>(Expression query, CancellationToken cancellationToken)
|
||||
{
|
||||
|
@ -66,35 +62,6 @@ namespace ShardingCore.EFCores
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
|
||||
|
||||
public IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression query)
|
||||
{
|
||||
return _shardingQueryExecutor.ExecuteAsync<IAsyncEnumerable<TResult>>(_currentContext, query);
|
||||
}
|
||||
|
||||
public Task<TResult> ExecuteAsync<TResult>(Expression query, CancellationToken cancellationToken)
|
||||
{
|
||||
return _shardingQueryExecutor.ExecuteAsync<Task<TResult>>(_currentContext, query, cancellationToken);
|
||||
}
|
||||
|
||||
public Func<QueryContext, TResult> CreateCompiledQuery<TResult>(Expression query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Func<QueryContext, IAsyncEnumerable<TResult>> CreateCompiledAsyncEnumerableQuery<TResult>(Expression query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Func<QueryContext, Task<TResult>> CreateCompiledAsyncTaskQuery<TResult>(Expression query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -28,36 +28,22 @@ namespace ShardingCore.EFCores
|
|||
private readonly IRelationalConnection _relationalConnection;
|
||||
|
||||
|
||||
#if !EFCORE2
|
||||
public ShardingRelationalConnection(IRelationalConnection _relationalConnection, DbTransaction transaction)
|
||||
{
|
||||
this._relationalConnection = _relationalConnection;
|
||||
((IShardingTransaction)Context).UseShardingTransaction(transaction);
|
||||
}
|
||||
|
||||
#endif
|
||||
#if EFCORE2
|
||||
private readonly Type _dbContextType;
|
||||
public ShardingRelationalConnection(IRelationalConnection _relationalConnection,DbTransaction transaction,Type dbContextType)
|
||||
{
|
||||
this._relationalConnection = _relationalConnection;
|
||||
_dbContextType = dbContextType;
|
||||
((IShardingTransaction)Context).UseShardingTransaction(transaction);
|
||||
}
|
||||
#endif
|
||||
|
||||
public void ResetState()
|
||||
{
|
||||
_relationalConnection.ResetState();
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
public Task ResetStateAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return _relationalConnection.ResetStateAsync(cancellationToken);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public IDbContextTransaction BeginTransaction()
|
||||
{
|
||||
|
@ -136,31 +122,7 @@ namespace ShardingCore.EFCores
|
|||
public DbConnection DbConnection => _relationalConnection.DbConnection;
|
||||
|
||||
public DbContext Context =>
|
||||
#if !EFCORE2
|
||||
_relationalConnection.Context;
|
||||
#endif
|
||||
#if EFCORE2
|
||||
GetDbContext();
|
||||
|
||||
private DbContext GetDbContext()
|
||||
{
|
||||
var namedConnectionStringResolver = ((RelationalConnectionDependencies)_relationalConnection.GetPropertyValue("Dependencies")).ConnectionStringResolver;
|
||||
var serviceProvider = (IServiceProvider)namedConnectionStringResolver.GetPropertyValue("ApplicationServiceProvider");
|
||||
var dbContext = (DbContext)serviceProvider.GetService(_dbContextType);
|
||||
return dbContext;
|
||||
}
|
||||
|
||||
|
||||
public void RegisterBufferable(IBufferable bufferable)
|
||||
{
|
||||
_relationalConnection.RegisterBufferable(bufferable);
|
||||
}
|
||||
|
||||
public Task RegisterBufferableAsync(IBufferable bufferable, CancellationToken cancellationToken)
|
||||
{
|
||||
return _relationalConnection.RegisterBufferableAsync(bufferable, cancellationToken);
|
||||
}
|
||||
#endif
|
||||
public Guid ConnectionId => _relationalConnection.ConnectionId;
|
||||
|
||||
public int? CommandTimeout
|
||||
|
@ -201,7 +163,6 @@ namespace ShardingCore.EFCores
|
|||
|
||||
|
||||
public string ConnectionString => _relationalConnection.ConnectionString;
|
||||
#if !EFCORE2
|
||||
|
||||
public async Task<IDbContextTransaction> UseTransactionAsync(DbTransaction transaction, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
|
@ -220,6 +181,5 @@ namespace ShardingCore.EFCores
|
|||
{
|
||||
return _relationalConnection.DisposeAsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ namespace ShardingCore.EFCores
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
#if !EFCORE2
|
||||
public class ShardingRelationalTransactionFactory: RelationalTransactionFactory
|
||||
{
|
||||
private readonly RelationalTransactionFactoryDependencies _dependencies;
|
||||
|
@ -31,23 +30,4 @@ namespace ShardingCore.EFCores
|
|||
return new RelationalTransaction(new ShardingRelationalConnection(connection, transaction), transaction, transactionId, logger, transactionOwned);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
|
||||
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
private readonly RelationalTransactionFactoryDependencies _dependencies;
|
||||
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)
|
||||
{
|
||||
_dependencies = dependencies;
|
||||
}
|
||||
public override RelationalTransaction Create(IRelationalConnection connection, DbTransaction transaction
|
||||
, IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger,
|
||||
bool transactionOwned)
|
||||
{
|
||||
return new RelationalTransaction(new ShardingRelationalConnection(connection, transaction,typeof(TShardingDbContext)), transaction, logger,
|
||||
transactionOwned);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Exceptions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 14:08:08
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class ShardingCoreNotSupportedException:NotSupportedException
|
||||
{
|
||||
public ShardingCoreNotSupportedException()
|
||||
{
|
||||
}
|
||||
|
||||
protected ShardingCoreNotSupportedException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
|
||||
public ShardingCoreNotSupportedException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ShardingCoreNotSupportedException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,29 +71,6 @@ namespace ShardingCore.Extensions
|
|||
return false;
|
||||
return typeof(IShardingTableDbContext).IsAssignableFrom(dbContextType);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否基继承至IShardingTable
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingTable(this Type entityType)
|
||||
{
|
||||
if (entityType == null)
|
||||
throw new ArgumentNullException(nameof(entityType));
|
||||
return typeof(IShardingTable).IsAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否基继承至IShardingTable
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingTable(this object entity)
|
||||
{
|
||||
if (entity == null)
|
||||
throw new ArgumentNullException(nameof(entity));
|
||||
return entity is IShardingTable;
|
||||
}
|
||||
// /// <summary>
|
||||
// /// 虚拟表转换成对应的db配置
|
||||
// /// </summary>
|
||||
|
|
|
@ -108,18 +108,6 @@ var contextModelRelationalModel = contextModel.RelationalModel as RelationalMode
|
|||
IMemoryCache memoryCache = modelSourceDependencies.MemoryCache;
|
||||
object key1 = modelSourceDependencies.ModelCacheKeyFactory.Create(dbContext);
|
||||
memoryCache.Remove(key1);
|
||||
#endif
|
||||
#if EFCORE2
|
||||
|
||||
var modelSource = serviceScope.ServiceProvider.GetService<IModelSource>();
|
||||
var modelSourceImpl = modelSource as RelationalModelSource;
|
||||
|
||||
var modelSourceDependencies =
|
||||
modelSourceImpl.GetPropertyValue("Dependencies") as ModelSourceDependencies;
|
||||
var models =
|
||||
typeof(ModelSource).GetTypeFieldValue(modelSourceImpl, "_models") as ConcurrentDictionary<object, Lazy<IModel>>;
|
||||
object key1 = modelSourceDependencies.ModelCacheKeyFactory.Create(dbContext);
|
||||
models.TryRemove(key1,out var del);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -145,9 +133,6 @@ var contextModelRelationalModel = contextModel.RelationalModel as RelationalMode
|
|||
var syncObject = modelSourceImpl.GetFieldValue("_syncObject");
|
||||
return syncObject;
|
||||
#endif
|
||||
#if EFCORE2
|
||||
return sLock;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ using System.Text;
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
@ -57,13 +57,11 @@ namespace ShardingCore.Extensions
|
|||
|
||||
public static string ShardingPrint(this Expression expression)
|
||||
{
|
||||
|
||||
#if !EFCORE2
|
||||
return expression.Print();
|
||||
#endif
|
||||
#if EFCORE2
|
||||
return expression.ToString();
|
||||
#endif
|
||||
}
|
||||
public static string ShardingPrint<T>(this IQueryable<T> queryable)
|
||||
{
|
||||
return queryable.Expression.ShardingPrint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.PhysicTables;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
|
||||
namespace ShardingCore.Extensions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 9:35:11
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public static class VirtualDataBaseExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否基继承至IShardingDataSource
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingDataSource(this Type entityType)
|
||||
{
|
||||
if (entityType == null)
|
||||
throw new ArgumentNullException(nameof(entityType));
|
||||
return typeof(IShardingDataSource).IsAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否基继承至IShardingDataSource
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingDataSource(this object entity)
|
||||
{
|
||||
if (entity == null)
|
||||
throw new ArgumentNullException(nameof(entity));
|
||||
return entity is IShardingDataSource;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否基继承至IShardingTable
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingTable(this Type entityType)
|
||||
{
|
||||
if (entityType == null)
|
||||
throw new ArgumentNullException(nameof(entityType));
|
||||
return typeof(IShardingTable).IsAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否基继承至IShardingTable
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsShardingTable(this object entity)
|
||||
{
|
||||
if (entity == null)
|
||||
throw new ArgumentNullException(nameof(entity));
|
||||
return entity is IShardingTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string GetTableTail<TEntity>(this IVirtualTableManager virtualTableManager, Type shardingDbContextType,string dsname,
|
||||
TEntity entity) where TEntity : class
|
||||
{
|
||||
if (entity.IsShardingTable())
|
||||
return string.Empty;
|
||||
var physicTable = virtualTableManager.GetVirtualTable(shardingDbContextType,dsname, entity.GetType()).RouteTo(new ShardingTableRouteConfig(null, entity as IShardingTable, null))[0];
|
||||
return physicTable.Tail;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Extensions
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/16 16:42:59
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public static class VirtualDataSourceManagerExtension
|
||||
{
|
||||
public static IVirtualDataSource<TEntity> GetVirtualDataSource<TShardingDbContext,TEntity>(this IVirtualDataSourceManager virtualDataSourceManager)
|
||||
where TShardingDbContext:DbContext,IShardingDbContext
|
||||
where TEntity : class,IShardingDataSource
|
||||
{
|
||||
return (IVirtualDataSource<TEntity>)virtualDataSourceManager.GetVirtualDataSource(typeof(TShardingDbContext), typeof(TEntity));
|
||||
}
|
||||
public static string GetDataSourceName<TEntity>(this IVirtualDataSourceManager virtualDataSourceManager, Type shardingDbContextType, TEntity entity) where TEntity : class
|
||||
{
|
||||
return virtualDataSourceManager.GetPhysicDataSource(shardingDbContextType, entity).DSName;
|
||||
}
|
||||
public static IPhysicDataSource GetPhysicDataSource<TEntity>(this IVirtualDataSourceManager virtualDataSourceManager, Type shardingDbContextType, TEntity entity) where TEntity : class
|
||||
{
|
||||
var type = entity.GetType();
|
||||
if (!entity.IsShardingDataSource())
|
||||
return virtualDataSourceManager.GetDefaultDataSource(shardingDbContextType);
|
||||
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource(type);
|
||||
return virtualDataSource.RouteTo(
|
||||
new ShardingDataSourceRouteConfig(shardingDataSource: entity as IShardingDataSource))[0];
|
||||
}
|
||||
|
||||
public static List<string> GetDataSourceNames<TEntity>(this IVirtualDataSourceManager virtualDataSourceManager, Type shardingDbContextType, Expression<Func<TEntity, bool>> where)
|
||||
where TEntity : class
|
||||
{
|
||||
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource(shardingDbContextType, typeof(TEntity));
|
||||
return virtualDataSource.RouteTo(new ShardingDataSourceRouteConfig(predicate: where)).Select(o => o.DSName)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.DbContexts.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
|
|
|
@ -2,7 +2,6 @@ using Microsoft.EntityFrameworkCore;
|
|||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualTables;
|
||||
using ShardingCore.DbContexts;
|
||||
|
@ -21,6 +20,8 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Core.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
{
|
||||
|
@ -36,21 +37,22 @@ namespace ShardingCore.Sharding
|
|||
/// <typeparam name="T"></typeparam>
|
||||
public abstract class AbstractShardingDbContext<T> : DbContext, IShardingDbContext<T>, IShardingTransaction, IShardingReadWriteSupport where T : DbContext, IShardingTableDbContext
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
||||
//private readonly ConcurrentDictionary<string, DbContext> _dbContextCaches = new ConcurrentDictionary<string, DbContext>();
|
||||
private readonly ConcurrentDictionary<string, ConcurrentDictionary<string,DbContext>> _dbContextCaches = new ConcurrentDictionary<string, ConcurrentDictionary<string, DbContext>>();
|
||||
private readonly IShardingConfigOption shardingConfigOption;
|
||||
private readonly IVirtualDataSourceManager _virtualDataSourceManager;
|
||||
private readonly IVirtualTableManager _virtualTableManager;
|
||||
private readonly IRouteTailFactory _routeTailFactory;
|
||||
private readonly IShardingDbContextFactory _shardingDbContextFactory;
|
||||
private readonly IShardingDbContextOptionsBuilderConfig _shardingDbContextOptionsBuilderConfig;
|
||||
private readonly IReadWriteOptions _readWriteOptions;
|
||||
private readonly IConnectionStringManager _connectionStringManager;
|
||||
private DbContextOptions<T> _dbContextOptions;
|
||||
|
||||
private readonly object CREATELOCK = new object();
|
||||
|
||||
public AbstractShardingDbContext(DbContextOptions options) : base(options)
|
||||
{
|
||||
_shardingDbContextFactory = ShardingContainer.GetService<IShardingDbContextFactory>();
|
||||
_virtualDataSourceManager = ShardingContainer.GetService<IVirtualDataSourceManager>();
|
||||
_virtualTableManager = ShardingContainer.GetService<IVirtualTableManager>();
|
||||
_routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
|
||||
_shardingDbContextOptionsBuilderConfig = ShardingContainer
|
||||
|
@ -91,13 +93,13 @@ namespace ShardingCore.Sharding
|
|||
return _readWriteOptions.ReadConnStringGetStrategy;
|
||||
}
|
||||
|
||||
public string GetWriteConnectionString()
|
||||
public string GetWriteConnectionString(string dsName)
|
||||
{
|
||||
return GetConnectionString();
|
||||
return GetConnectionString(dsName);
|
||||
}
|
||||
public string GetConnectionString()
|
||||
public string GetConnectionString(string dsName)
|
||||
{
|
||||
return Database.GetDbConnection().ConnectionString;
|
||||
return _virtualDataSourceManager.GetDataSource(dsName).ConnectionString;
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,100 +110,126 @@ namespace ShardingCore.Sharding
|
|||
return (DbContextOptionsBuilder<T>)Activator.CreateInstance(type);
|
||||
}
|
||||
|
||||
private DbContextOptions<T> CreateShareDbContextOptions()
|
||||
private DbContextOptions<T> CreateShareDbContextOptions(string dsName)
|
||||
{
|
||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||
var dbConnection = Database.GetDbConnection();
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
||||
|
||||
if (!_dbContextCaches.TryGetValue(dsName, out var sameConnectionDbContexts))
|
||||
{
|
||||
sameConnectionDbContexts = new ConcurrentDictionary<string, DbContext>();
|
||||
_dbContextCaches.TryAdd(dsName, sameConnectionDbContexts);
|
||||
}
|
||||
//存在使用相同的connection创建 第一次使用字符串创建
|
||||
if (sameConnectionDbContexts.Any())
|
||||
{
|
||||
var dbConnection = sameConnectionDbContexts.First().Value.Database.GetDbConnection();
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(dbConnection, dbContextOptionBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
var physicDataSource = _virtualDataSourceManager.GetDataSource(dsName);
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(physicDataSource.ConnectionString, dbContextOptionBuilder);
|
||||
}
|
||||
|
||||
return dbContextOptionBuilder.Options;
|
||||
}
|
||||
private DbContextOptions<T> CreateParallelDbContextOptions()
|
||||
private ShardingDbContextOptions GetShareShardingDbContextOptions(string dsName,IRouteTail routeTail)
|
||||
{
|
||||
var dbContextOptions=CreateShareDbContextOptions(dsName);
|
||||
|
||||
return new ShardingDbContextOptions(dbContextOptions, routeTail);
|
||||
}
|
||||
private DbContextOptions<T> CreateParallelDbContextOptions(string dsName)
|
||||
{
|
||||
var dbContextOptionBuilder = CreateDbContextOptionBuilder();
|
||||
var connectionString = _connectionStringManager.GetConnectionString(this);
|
||||
var connectionString = _connectionStringManager.GetConnectionString(dsName,this);
|
||||
_shardingDbContextOptionsBuilderConfig.UseDbContextOptionsBuilder(connectionString, dbContextOptionBuilder);
|
||||
return dbContextOptionBuilder.Options;
|
||||
}
|
||||
|
||||
private ShardingDbContextOptions GetShareShardingDbContextOptions(IRouteTail routeTail)
|
||||
private ShardingDbContextOptions CetParallelShardingDbContextOptions(string dsName, IRouteTail routeTail)
|
||||
{
|
||||
if (_dbContextOptions == null)
|
||||
{
|
||||
lock (CREATELOCK)
|
||||
{
|
||||
if (_dbContextOptions == null)
|
||||
{
|
||||
_dbContextOptions = CreateShareDbContextOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new ShardingDbContextOptions(_dbContextOptions, routeTail);
|
||||
}
|
||||
private ShardingDbContextOptions CetParallelShardingDbContextOptions(IRouteTail routeTail)
|
||||
{
|
||||
return new ShardingDbContextOptions(CreateParallelDbContextOptions(), routeTail);
|
||||
return new ShardingDbContextOptions(CreateParallelDbContextOptions(dsName), routeTail);
|
||||
}
|
||||
|
||||
|
||||
public DbContext GetDbContext(bool track, IRouteTail routeTail)
|
||||
public DbContext GetDbContext(string dsName,bool track, IRouteTail routeTail)
|
||||
{
|
||||
if (track)
|
||||
{
|
||||
if (routeTail.IsMultiEntityQuery())
|
||||
throw new ShardingCoreException("multi route not support track");
|
||||
throw new ShardingCoreNotSupportedException("multi route not support track");
|
||||
if (!(routeTail is ISingleQueryRouteTail singleQueryRouteTail))
|
||||
throw new ShardingCoreException("multi route not support track");
|
||||
var cacheKey = routeTail.GetRouteTailIdentity();
|
||||
if (!_dbContextCaches.TryGetValue(cacheKey, out var dbContext))
|
||||
throw new ShardingCoreNotSupportedException("multi route not support track");
|
||||
if (!_dbContextCaches.TryGetValue(dsName, out var tailDbContexts))
|
||||
{
|
||||
dbContext = _shardingDbContextFactory.Create(ShardingDbContextType, GetShareShardingDbContextOptions(routeTail));
|
||||
tailDbContexts = new ConcurrentDictionary<string, DbContext>();
|
||||
_dbContextCaches.TryAdd(dsName, tailDbContexts);
|
||||
}
|
||||
var cacheKey = routeTail.GetRouteTailIdentity();
|
||||
if (!tailDbContexts.TryGetValue(cacheKey, out var dbContext))
|
||||
{
|
||||
dbContext = _shardingDbContextFactory.Create(ShardingDbContextType, GetShareShardingDbContextOptions(dsName,routeTail));
|
||||
if (IsBeginTransaction)
|
||||
dbContext.Database.UseTransaction(Database.CurrentTransaction.GetDbTransaction());
|
||||
|
||||
_dbContextCaches.TryAdd(cacheKey, dbContext);
|
||||
tailDbContexts.TryAdd(cacheKey, dbContext);
|
||||
}
|
||||
return dbContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _shardingDbContextFactory.Create(ShardingDbContextType, CetParallelShardingDbContextOptions(routeTail));
|
||||
return _shardingDbContextFactory.Create(ShardingDbContextType, CetParallelShardingDbContextOptions(dsName,routeTail));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsBeginTransaction => Database.CurrentTransaction != null;
|
||||
|
||||
/// <summary>
|
||||
/// 根据对象创建通用的dbcontext
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
public DbContext CreateGenericDbContext<T>(T entity) where T : class
|
||||
{
|
||||
var tail = string.Empty;
|
||||
if (entity.IsShardingTable())
|
||||
{
|
||||
var physicTable = _virtualTableManager.GetVirtualTable(ShardingDbContextType, entity.GetType()).RouteTo(new TableRouteConfig(null, entity as IShardingTable, null))[0];
|
||||
tail = physicTable.Tail;
|
||||
}
|
||||
var dsname = _virtualDataSourceManager.GetDataSourceName(ShardingDbContextType,entity);
|
||||
var tail = _virtualTableManager.GetTableTail(ShardingDbContextType, dsname,entity);
|
||||
|
||||
return GetDbContext(true, _routeTailFactory.Create(tail));
|
||||
return GetDbContext(dsname,true, _routeTailFactory.Create(tail));
|
||||
}
|
||||
|
||||
public IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> @where) where TEntity : class
|
||||
{
|
||||
var dsNames = _virtualDataSourceManager.GetDataSourceNames(ShardingDbContextType, @where);
|
||||
|
||||
if (typeof(TEntity).IsShardingTable())
|
||||
{
|
||||
var physicTable = _virtualTableManager.GetVirtualTable(ShardingDbContextType, typeof(TEntity)).RouteTo(new TableRouteConfig(predicate: @where));
|
||||
if (physicTable.IsEmpty())
|
||||
throw new ShardingCoreException($"{@where.ShardingPrint()} cant found ant physic table");
|
||||
return physicTable.Select(o => GetDbContext(true, _routeTailFactory.Create(o.Tail)));
|
||||
var resultDbContexts = new LinkedList<DbContext>();
|
||||
foreach (var dsName in dsNames)
|
||||
{
|
||||
var physicTable = _virtualTableManager.GetVirtualTable(ShardingDbContextType, dsName, typeof(TEntity)).RouteTo(new ShardingTableRouteConfig(predicate: @where));
|
||||
if (physicTable.IsEmpty())
|
||||
throw new ShardingCoreException($"{@where.ShardingPrint()} cant found ant physic table");
|
||||
var dbContexts = physicTable.Select(o => GetDbContext(dsName, true, _routeTailFactory.Create(o.Tail))).ToList();
|
||||
foreach (var dbContext in dbContexts)
|
||||
{
|
||||
resultDbContexts.AddLast(dbContext);
|
||||
}
|
||||
}
|
||||
|
||||
return resultDbContexts;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new[] { GetDbContext(true, _routeTailFactory.Create(string.Empty)) };
|
||||
return dsNames.Select(dsName => GetDbContext(dsName, true, _routeTailFactory.Create(string.Empty)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UseShardingTransaction(DbTransaction transaction)
|
||||
{
|
||||
_dbContextCaches.Values.ForEach(o => o.Database.UseTransaction(transaction));
|
||||
throw new NotImplementedException();
|
||||
//_dbContextCaches.Values.ForEach(o => o.Database.UseTransaction(transaction));
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,7 +243,6 @@ namespace ShardingCore.Sharding
|
|||
return CreateGenericDbContext(entity).Add(entity);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public override ValueTask<EntityEntry<TEntity>> AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
|
@ -226,18 +253,6 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public override Task<EntityEntry<TEntity>> AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
||||
}
|
||||
|
||||
public override Task<EntityEntry> AddAsync(object entity, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
public override void AddRange(params object[] entities)
|
||||
{
|
||||
|
@ -466,31 +481,7 @@ namespace ShardingCore.Sharding
|
|||
|
||||
public override int SaveChanges()
|
||||
{
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
|
||||
int i = 0;
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
using (var tran = Database.BeginTransaction())
|
||||
{
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += dbContextCache.Value.SaveChanges();
|
||||
}
|
||||
tran.Commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += dbContextCache.Value.SaveChanges();
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
return this.SaveChanges(true);
|
||||
}
|
||||
|
||||
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
||||
|
@ -520,68 +511,12 @@ namespace ShardingCore.Sharding
|
|||
|
||||
return i;
|
||||
}
|
||||
#if !EFCORE2
|
||||
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
|
||||
int i = 0;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
using (var tran = await Database.BeginTransactionAsync(cancellationToken))
|
||||
{
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += await dbContextCache.Value.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
await tran.CommitAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += await dbContextCache.Value.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
return this.SaveChangesAsync(true,cancellationToken);
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
int i = 0;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
using (var tran = await Database.BeginTransactionAsync(cancellationToken))
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += await dbContextCache.Value.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
tran.Commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += await dbContextCache.Value.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
#if !EFCORE2
|
||||
|
||||
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
|
@ -614,37 +549,6 @@ namespace ShardingCore.Sharding
|
|||
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
|
||||
var isBeginTransaction = IsBeginTransaction;
|
||||
int i = 0;
|
||||
//如果是内部开的事务就内部自己消化
|
||||
if (!isBeginTransaction)
|
||||
{
|
||||
using (var tran = await Database.BeginTransactionAsync(cancellationToken))
|
||||
{
|
||||
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += await dbContextCache.Value.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||
}
|
||||
|
||||
tran.Commit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
{
|
||||
i += await dbContextCache.Value.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
|
@ -663,7 +567,6 @@ namespace ShardingCore.Sharding
|
|||
base.Dispose();
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
public override async ValueTask DisposeAsync()
|
||||
{
|
||||
foreach (var dbContextCache in _dbContextCaches)
|
||||
|
@ -680,6 +583,5 @@ namespace ShardingCore.Sharding
|
|||
|
||||
await base.DisposeAsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -15,6 +15,6 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
public interface IConnectionStringManager
|
||||
{
|
||||
Type ShardingDbContextType { get; }
|
||||
string GetConnectionString(IShardingDbContext shardingDbContext);
|
||||
string GetConnectionString(string dsName,IShardingDbContext shardingDbContext);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq.Expressions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.Abstractions
|
||||
{
|
||||
|
@ -26,10 +26,11 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
/// <summary>
|
||||
/// create DbContext
|
||||
/// </summary>
|
||||
/// <param name="dsName">data source name</param>
|
||||
/// <param name="track">true not care db context life, false need call dispose()</param>
|
||||
/// <param name="routeTail"></param>
|
||||
/// <returns></returns>
|
||||
DbContext GetDbContext(bool track,IRouteTail routeTail);
|
||||
DbContext GetDbContext(string dsName,bool track,IRouteTail routeTail);
|
||||
/// <summary>
|
||||
/// 创建通用的db context
|
||||
/// </summary>
|
||||
|
@ -47,7 +48,7 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> where)
|
||||
where TEntity : class;
|
||||
|
||||
string GetConnectionString();
|
||||
string GetConnectionString(string dsName);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@ using System.Linq.Expressions;
|
|||
using System.Threading;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
#if EFCORE2
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
#endif
|
||||
|
||||
namespace ShardingCore.Sharding.Abstractions
|
||||
{
|
||||
|
|
|
@ -17,6 +17,6 @@ namespace ShardingCore.Sharding.Abstractions
|
|||
int ReadWritePriority { get; set; }
|
||||
bool ReadWriteSupport { get; set; }
|
||||
ReadConnStringGetStrategyEnum GetReadConnStringGetStrategy();
|
||||
string GetWriteConnectionString();
|
||||
string GetWriteConnectionString(string dsName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.Abstractions
|
||||
{
|
||||
|
|
|
@ -24,7 +24,6 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
{
|
||||
_inMemoryStreamMergeAsyncEnumerator = inMemoryStreamMergeAsyncEnumerator;
|
||||
}
|
||||
#if !EFCORE2
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await _inMemoryStreamMergeAsyncEnumerator.DisposeAsync();
|
||||
|
@ -47,25 +46,6 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
|
||||
return _reverseEnumerator.MoveNext();
|
||||
}
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public async Task<bool> MoveNext(CancellationToken cancellationToken)
|
||||
{
|
||||
if (_first)
|
||||
{
|
||||
LinkedList<T> _reverseCollection = new LinkedList<T>();
|
||||
while (await _inMemoryStreamMergeAsyncEnumerator.MoveNext(cancellationToken))
|
||||
{
|
||||
_reverseCollection.AddFirst(_inMemoryStreamMergeAsyncEnumerator.GetCurrent());
|
||||
}
|
||||
|
||||
_reverseEnumerator = _reverseCollection.GetEnumerator();
|
||||
_first = false;
|
||||
}
|
||||
|
||||
return _reverseEnumerator.MoveNext();
|
||||
}
|
||||
#endif
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
|
|
|
@ -56,21 +56,11 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
return _mergeContext.SelectContext.SelectProperties.Where(o => !o.IsAggregateMethod)
|
||||
.Select(o => first.GetValueByExpression(o.PropertyName)).ToList();
|
||||
}
|
||||
#if !EFCORE2
|
||||
public async ValueTask<bool> MoveNextAsync()
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public async Task<bool> MoveNext(CancellationToken cancellationToken=new CancellationToken())
|
||||
#endif
|
||||
{
|
||||
if (_queue.IsEmpty())
|
||||
return false;
|
||||
#if !EFCORE2
|
||||
var hasNext = await SetCurrentValueAsync();
|
||||
#endif
|
||||
#if EFCORE2
|
||||
var hasNext = await SetCurrentValueAsync(cancellationToken);
|
||||
#endif
|
||||
if (hasNext)
|
||||
{
|
||||
CurrentGroupValues = _queue.IsEmpty() ? new List<object>(0) : GetCurrentGroupValues(_queue.Peek());
|
||||
|
@ -89,12 +79,7 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
|
||||
return true;
|
||||
}
|
||||
#if !EFCORE2
|
||||
private async ValueTask<bool> SetCurrentValueAsync()
|
||||
#endif
|
||||
#if EFCORE2
|
||||
private async Task<bool> SetCurrentValueAsync(CancellationToken cancellationToken=new CancellationToken())
|
||||
#endif
|
||||
{
|
||||
CurrentValue = default;
|
||||
var currentValues = new List<T>();
|
||||
|
@ -104,12 +89,7 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
currentValues.Add(current);
|
||||
var first = _queue.Poll();
|
||||
|
||||
#if !EFCORE2
|
||||
if (await first.MoveNextAsync())
|
||||
#endif
|
||||
#if EFCORE2
|
||||
if (await first.MoveNext(cancellationToken))
|
||||
#endif
|
||||
{
|
||||
_queue.Offer(first);
|
||||
}
|
||||
|
@ -223,7 +203,6 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
return CurrentValue;
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
|
@ -232,7 +211,6 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
await enumerator.DisposeAsync();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public void Reset()
|
||||
|
|
|
@ -45,12 +45,7 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
|
||||
_currentEnumerator = _queue.IsEmpty() ? _enumerators.FirstOrDefault() : _queue.Peek();
|
||||
}
|
||||
#if !EFCORE2
|
||||
public async ValueTask<bool> MoveNextAsync()
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public async Task<bool> MoveNext(CancellationToken cancellationToken = new CancellationToken())
|
||||
#endif
|
||||
{
|
||||
if (_queue.IsEmpty())
|
||||
return false;
|
||||
|
@ -61,14 +56,8 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
}
|
||||
|
||||
var first = _queue.Poll();
|
||||
#if !EFCORE2
|
||||
|
||||
if (await first.MoveNextAsync())
|
||||
#endif
|
||||
#if EFCORE2
|
||||
|
||||
if (await first.MoveNext(cancellationToken))
|
||||
#endif
|
||||
{
|
||||
_queue.Offer(first);
|
||||
}
|
||||
|
@ -128,7 +117,6 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
return _currentEnumerator.GetCurrent();
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
|
@ -137,7 +125,6 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
await enumerator.DisposeAsync();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -38,19 +38,9 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
_orderValues = HasElement() ? GetCurrentOrderValues() : new List<IComparable>(0);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
public async ValueTask<bool> MoveNextAsync()
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public async Task<bool> MoveNext(CancellationToken cancellationToken = new CancellationToken())
|
||||
#endif
|
||||
{
|
||||
#if !EFCORE2
|
||||
var has = await _enumerator.MoveNextAsync();
|
||||
#endif
|
||||
#if EFCORE2
|
||||
var has = await _enumerator.MoveNext(cancellationToken);
|
||||
#endif
|
||||
SetOrderValues();
|
||||
return has;
|
||||
}
|
||||
|
@ -129,12 +119,10 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
{
|
||||
return _orderValues ?? new List<IComparable>(0);
|
||||
}
|
||||
#if !EFCORE2
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
return _enumerator.DisposeAsync();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
|
@ -31,34 +31,19 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
else
|
||||
_enumerator = new MultiOrderStreamMergeAsyncEnumerator<T>(_mergeContext, sources);
|
||||
}
|
||||
#if !EFCORE2
|
||||
public async ValueTask<bool> MoveNextAsync()
|
||||
#endif
|
||||
#if EFCORE2
|
||||
public async Task<bool> MoveNext(CancellationToken cancellationToken = new CancellationToken())
|
||||
#endif
|
||||
{
|
||||
//如果合并数据的时候不需要跳过也没有take多少那么就是直接next
|
||||
while (_skip.GetValueOrDefault() > this.realSkip)
|
||||
{
|
||||
#if !EFCORE2
|
||||
var has = await _enumerator.MoveNextAsync();
|
||||
#endif
|
||||
#if EFCORE2
|
||||
var has = await _enumerator.MoveNext(cancellationToken);
|
||||
#endif
|
||||
|
||||
realSkip++;
|
||||
if (!has)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
var next = await _enumerator.MoveNextAsync();
|
||||
#endif
|
||||
#if EFCORE2
|
||||
var next = await _enumerator.MoveNext(cancellationToken);
|
||||
#endif
|
||||
|
||||
if (next)
|
||||
{
|
||||
|
@ -126,12 +111,9 @@ namespace ShardingCore.Sharding.Enumerators.StreamMergeAsync
|
|||
{
|
||||
_enumerator.Dispose();
|
||||
}
|
||||
#if !EFCORE2
|
||||
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
return _enumerator.DisposeAsync();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -43,7 +43,6 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#if !EFCORE2
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (_asyncSource != null)
|
||||
|
@ -96,7 +95,6 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
return _syncSource.MoveNext();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -106,68 +104,5 @@ namespace ShardingCore.Sharding.Enumerators
|
|||
}
|
||||
|
||||
object IEnumerator.Current => Current;
|
||||
#if EFCORE2
|
||||
public void Dispose()
|
||||
{
|
||||
_asyncSource.Dispose();
|
||||
}
|
||||
|
||||
public async Task<bool> MoveNext(CancellationToken cancellationToken=new CancellationToken())
|
||||
{
|
||||
if (skip)
|
||||
{
|
||||
skip = false;
|
||||
return null != SourceCurrent();
|
||||
}
|
||||
return await _asyncSource.MoveNext(cancellationToken);
|
||||
}
|
||||
public T Current => GetCurrent();
|
||||
public T ReallyCurrent => GetReallyCurrent();
|
||||
public bool HasElement()
|
||||
{
|
||||
return null != SourceCurrent();
|
||||
}
|
||||
|
||||
private T SourceCurrent()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (tryGetCurrentError)
|
||||
return default;
|
||||
return _asyncSource.Current;
|
||||
}catch(Exception e)
|
||||
{
|
||||
tryGetCurrentError = true;
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
private bool tryGetCurrentError = false;
|
||||
|
||||
public T GetCurrent()
|
||||
{
|
||||
if (skip)
|
||||
return default;
|
||||
if (_asyncSource != null) return SourceCurrent();
|
||||
if (_syncSource != null) return _syncSource.Current;
|
||||
return default;
|
||||
}
|
||||
public T GetReallyCurrent()
|
||||
{
|
||||
if (_asyncSource != null) return SourceCurrent();
|
||||
if (_syncSource != null) return _syncSource.Current;
|
||||
return default;
|
||||
}
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (skip)
|
||||
{
|
||||
skip = false;
|
||||
return null != _syncSource.Current;
|
||||
}
|
||||
return _syncSource.MoveNext();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Sharding.PaginationConfigurations.MultiQueryPagination
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/15 17:07:30
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface IMultiQueryPredicate
|
||||
{
|
||||
public bool Continue(long total, int currentSkip, int tables);
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public class PaginationBuilder<TEntity> where TEntity:class,IShardingTable
|
||||
public class PaginationBuilder<TEntity> where TEntity:class
|
||||
{
|
||||
private readonly PaginationMetadata _metadata;
|
||||
|
||||
|
@ -53,5 +53,14 @@ namespace ShardingCore.Sharding.PaginationConfigurations
|
|||
// _metadata.TakeInMemoryCountIfLe = count;
|
||||
// return this;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 启用多次查询排序
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public PaginationBuilder<TEntity> ConfigMultiQueryShardingPage()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,17 @@
|
|||
#if EFCORE2
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.DbContexts
|
||||
namespace ShardingCore.Sharding.PaginationConfigurations.ReversePagination
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/5 21:29:47
|
||||
* @Date: 2021/9/15 22:20:13
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
class EFCore2DbContextLocation
|
||||
public interface IReverserPredicate
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace ShardingCore.Sharding.PaginationConfigurations.SelectPrimaryKeyPagination
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: 2021/9/15 22:17:57
|
||||
* @Ver: 1.0
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
public interface ISelectPrimaryKeyPredicate
|
||||
{
|
||||
public bool ShouldUse(long total, int skip, int tables);
|
||||
}
|
||||
}
|
|
@ -28,11 +28,11 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
_shardingReadWriteManager = shardingReadWriteManager;
|
||||
_shardingConnectionStringResolver = shardingConnectionStringResolvers.FirstOrDefault(o => o.ShardingDbContextType == ShardingDbContextType) ?? throw new ArgumentNullException($"{ShardingDbContextType.FullName}:{nameof(shardingConnectionStringResolvers)}");
|
||||
}
|
||||
public string GetConnectionString(IShardingDbContext shardingDbContext)
|
||||
public string GetConnectionString(string dsName,IShardingDbContext shardingDbContext)
|
||||
{
|
||||
if (!(shardingDbContext is IShardingReadWriteSupport shardingReadWriteSupport))
|
||||
{
|
||||
return shardingDbContext.GetConnectionString();
|
||||
return shardingDbContext.GetConnectionString(dsName);
|
||||
}
|
||||
var shardingReadWriteContext = _shardingReadWriteManager.GetCurrent(ShardingDbContextType);
|
||||
var support = shardingReadWriteSupport.ReadWriteSupport;
|
||||
|
@ -47,7 +47,7 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
{
|
||||
return GetReadConnectionString0(shardingReadWriteSupport);
|
||||
}
|
||||
return shardingReadWriteSupport.GetWriteConnectionString();
|
||||
return shardingReadWriteSupport.GetWriteConnectionString(dsName);
|
||||
}
|
||||
private string GetReadConnectionString0(IShardingReadWriteSupport shardingReadWriteSupport)
|
||||
{
|
||||
|
|
|
@ -12,9 +12,6 @@ using ShardingCore.Sharding.Abstractions;
|
|||
using ShardingCore.Sharding.StreamMergeEngines;
|
||||
using ShardingCore.Sharding.StreamMergeEngines.Abstractions;
|
||||
using ShardingCore.Sharding.StreamMergeEngines.AggregateMergeEngines;
|
||||
#if EFCORE2
|
||||
using Microsoft.EntityFrameworkCore.Internal;
|
||||
#endif
|
||||
|
||||
namespace ShardingCore.Sharding.ShardingQueryExecutors
|
||||
{
|
||||
|
|
|
@ -3,11 +3,12 @@ using ShardingCore.Core.Internal.StreamMerge.ReWrite;
|
|||
using ShardingCore.Core.Internal.Visitors;
|
||||
using ShardingCore.Core.Internal.Visitors.GroupBys;
|
||||
using ShardingCore.Core.Internal.Visitors.Selects;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
|
@ -23,26 +24,29 @@ namespace ShardingCore.Sharding
|
|||
//private readonly IShardingScopeFactory _shardingScopeFactory;
|
||||
private readonly IQueryable<T> _source;
|
||||
private readonly IShardingDbContext _shardingDbContext;
|
||||
private readonly IRoutingRuleEngineFactory _tableRoutingRuleEngineFactory;
|
||||
private readonly IDataSourceRouteRuleEngineFactory _dataSourceRouteRuleEngineFactory;
|
||||
private readonly ITableRouteRuleEngineFactory _tableTableRouteRuleEngineFactory;
|
||||
private readonly IRouteTailFactory _routeTailFactory;
|
||||
|
||||
private readonly IQueryable<T> _reWriteSource;
|
||||
//public IEnumerable<RouteResult> RouteResults { get; }
|
||||
//public DataSourceRoutingResult RoutingResult { get; }
|
||||
//public IEnumerable<TableRouteResult> RouteResults { get; }
|
||||
//public DataSourceRouteResult RoutingResult { get; }
|
||||
public int? Skip { get; private set; }
|
||||
public int? Take { get; }
|
||||
public IEnumerable<PropertyOrder> Orders { get; private set; }
|
||||
|
||||
public SelectContext SelectContext { get;}
|
||||
public GroupByContext GroupByContext { get; }
|
||||
public IEnumerable<RouteResult> RouteResults { get; }
|
||||
//public IEnumerable<TableRouteResult> RouteResults { get; }
|
||||
public DataSourceRouteResult DataSourceRouteResult { get; }
|
||||
|
||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext,IRoutingRuleEngineFactory tableRoutingRuleEngineFactory, IRouteTailFactory routeTailFactory)
|
||||
public StreamMergeContext(IQueryable<T> source,IShardingDbContext shardingDbContext, IDataSourceRouteRuleEngineFactory dataSourceRouteRuleEngineFactory, ITableRouteRuleEngineFactory tableTableRouteRuleEngineFactory, IRouteTailFactory routeTailFactory)
|
||||
{
|
||||
//_shardingScopeFactory = shardingScopeFactory;
|
||||
_source = source;
|
||||
_shardingDbContext = shardingDbContext;
|
||||
_tableRoutingRuleEngineFactory = tableRoutingRuleEngineFactory;
|
||||
_dataSourceRouteRuleEngineFactory = dataSourceRouteRuleEngineFactory;
|
||||
_tableTableRouteRuleEngineFactory = tableTableRouteRuleEngineFactory;
|
||||
_routeTailFactory = routeTailFactory;
|
||||
var reWriteResult = new ReWriteEngine<T>(source).ReWrite();
|
||||
Skip = reWriteResult.Skip;
|
||||
|
@ -51,9 +55,11 @@ namespace ShardingCore.Sharding
|
|||
SelectContext = reWriteResult.SelectContext;
|
||||
GroupByContext = reWriteResult.GroupByContext;
|
||||
_reWriteSource = reWriteResult.ReWriteQueryable;
|
||||
RouteResults = _tableRoutingRuleEngineFactory.Route(_shardingDbContext.GetType(), _source);
|
||||
DataSourceRouteResult =
|
||||
dataSourceRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
|
||||
//RouteResults = _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, _source);
|
||||
}
|
||||
//public StreamMergeContext(IQueryable<T> source,IEnumerable<RouteResult> routeResults,
|
||||
//public StreamMergeContext(IQueryable<T> source,IEnumerable<TableRouteResult> routeResults,
|
||||
// IShardingParallelDbContextFactory shardingParallelDbContextFactory,IShardingScopeFactory shardingScopeFactory)
|
||||
//{
|
||||
// _shardingParallelDbContextFactory = shardingParallelDbContextFactory;
|
||||
|
@ -77,15 +83,21 @@ namespace ShardingCore.Sharding
|
|||
{
|
||||
Skip = skip;
|
||||
}
|
||||
public DbContext CreateDbContext(RouteResult routeResult)
|
||||
/// <summary>
|
||||
/// ´´½¨¶ÔÓ¦µÄdbcontext
|
||||
/// </summary>
|
||||
/// <param name="dsname">data source name</param>
|
||||
/// <param name="tableRouteResult"></param>
|
||||
/// <returns></returns>
|
||||
public DbContext CreateDbContext(string dsname,TableRouteResult tableRouteResult)
|
||||
{
|
||||
var routeTail = _routeTailFactory.Create(routeResult);
|
||||
return _shardingDbContext.GetDbContext(false, routeTail);
|
||||
var routeTail = _routeTailFactory.Create(tableRouteResult);
|
||||
return _shardingDbContext.GetDbContext(dsname,false, routeTail);
|
||||
}
|
||||
|
||||
public IRouteTail Create(RouteResult routeResult)
|
||||
public IRouteTail Create(TableRouteResult tableRouteResult)
|
||||
{
|
||||
return _routeTailFactory.Create(routeResult);
|
||||
return _routeTailFactory.Create(tableRouteResult);
|
||||
}
|
||||
|
||||
public IQueryable<T> GetReWriteQueryable()
|
||||
|
@ -123,5 +135,9 @@ namespace ShardingCore.Sharding
|
|||
return _shardingDbContext;
|
||||
}
|
||||
|
||||
public IEnumerable<TableRouteResult> GetTableRouteResults(string dsname)
|
||||
{
|
||||
return _tableTableRouteRuleEngineFactory.Route(_shardingDbContext.ShardingDbContextType, dsname, _source);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RoutingRuleEngine;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using System.Linq;
|
||||
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding
|
||||
{
|
||||
|
@ -13,18 +14,20 @@ namespace ShardingCore.Sharding
|
|||
*/
|
||||
public class StreamMergeContextFactory:IStreamMergeContextFactory
|
||||
{
|
||||
private readonly IRoutingRuleEngineFactory _routingRuleEngineFactory;
|
||||
private readonly IDataSourceRouteRuleEngineFactory _dataSourceRouteRuleEngineFactory;
|
||||
private readonly ITableRouteRuleEngineFactory _tableRouteRuleEngineFactory;
|
||||
private readonly IRouteTailFactory _routeTailFactory;
|
||||
|
||||
public StreamMergeContextFactory(
|
||||
IRoutingRuleEngineFactory routingRuleEngineFactory,IRouteTailFactory routeTailFactory)
|
||||
public StreamMergeContextFactory(IDataSourceRouteRuleEngineFactory dataSourceRouteRuleEngineFactory,
|
||||
ITableRouteRuleEngineFactory tableRouteRuleEngineFactory,IRouteTailFactory routeTailFactory)
|
||||
{
|
||||
_routingRuleEngineFactory = routingRuleEngineFactory;
|
||||
_dataSourceRouteRuleEngineFactory = dataSourceRouteRuleEngineFactory;
|
||||
_tableRouteRuleEngineFactory = tableRouteRuleEngineFactory;
|
||||
_routeTailFactory = routeTailFactory;
|
||||
}
|
||||
public StreamMergeContext<T> Create<T>(IQueryable<T> queryable,IShardingDbContext shardingDbContext)
|
||||
{
|
||||
return new StreamMergeContext<T>(queryable,shardingDbContext, _routingRuleEngineFactory, _routeTailFactory);
|
||||
return new StreamMergeContext<T>(queryable,shardingDbContext, _dataSourceRouteRuleEngineFactory, _tableRouteRuleEngineFactory, _routeTailFactory);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureExpressionMergeEngines
|
||||
|
@ -26,12 +27,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureEx
|
|||
if (!(secondExpression is ConstantExpression constantExpression))
|
||||
{
|
||||
|
||||
#if !EFCORE2
|
||||
throw new ShardingCoreException($"not found constant {methodCallExpression.Print()}");
|
||||
#endif
|
||||
#if EFCORE2
|
||||
throw new ShardingCoreException($"not found constant {methodCallExpression}");
|
||||
#endif
|
||||
throw new ShardingCoreException($"not found constant {methodCallExpression.ShardingPrint()}");
|
||||
}
|
||||
_constantItem = (TEntity)constantExpression.Value;
|
||||
}
|
||||
|
@ -39,12 +35,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureEx
|
|||
{
|
||||
if (!(secondExpression is ConstantExpression))
|
||||
{
|
||||
#if !EFCORE2
|
||||
throw new InvalidOperationException(_methodCallExpression.Print());
|
||||
#endif
|
||||
#if EFCORE2
|
||||
throw new InvalidOperationException(_methodCallExpression.ToString());
|
||||
#endif
|
||||
throw new InvalidOperationException(_methodCallExpression.ShardingPrint());
|
||||
}
|
||||
|
||||
return queryable;
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureExpressionMergeEngines
|
||||
|
@ -31,12 +32,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureEx
|
|||
return queryable.Select(selector);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
throw new ShardingCoreException($"expression is not selector:{secondExpression.Print()}");
|
||||
#endif
|
||||
#if EFCORE2
|
||||
throw new ShardingCoreException($"expression is not selector:{secondExpression}");
|
||||
#endif
|
||||
throw new ShardingCoreException($"expression is not selector:{secondExpression.ShardingPrint()}");
|
||||
}
|
||||
return queryable;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureExpressionMergeEngines
|
||||
|
@ -29,12 +30,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractEnsureEx
|
|||
return queryable.Where(predicate);
|
||||
}
|
||||
|
||||
#if !EFCORE2
|
||||
throw new InvalidOperationException(_methodCallExpression.Print());
|
||||
#endif
|
||||
#if EFCORE2
|
||||
throw new InvalidOperationException(_methodCallExpression.ToString());
|
||||
#endif
|
||||
throw new InvalidOperationException(_methodCallExpression.ShardingPrint());
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractGenericExpressionMergeEngines
|
||||
|
@ -30,13 +31,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractGenericE
|
|||
return queryable.Select(selector);
|
||||
}
|
||||
|
||||
|
||||
#if !EFCORE2
|
||||
throw new ShardingCoreException($"expression is not selector:{secondExpression.Print()}");
|
||||
#endif
|
||||
#if EFCORE2
|
||||
throw new ShardingCoreException($"expression is not selector:{secondExpression}");
|
||||
#endif
|
||||
throw new ShardingCoreException($"expression is not selector:{secondExpression.ShardingPrint()}");
|
||||
}
|
||||
return queryable;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractGenericExpressionMergeEngines
|
||||
|
@ -31,12 +32,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions.AbstractGenericE
|
|||
return queryable.Where(predicate);
|
||||
}
|
||||
}
|
||||
#if !EFCORE2
|
||||
throw new InvalidOperationException(_methodCallExpression.Print());
|
||||
#endif
|
||||
#if EFCORE2
|
||||
throw new InvalidOperationException(_methodCallExpression.ToString());
|
||||
#endif
|
||||
throw new InvalidOperationException(_methodCallExpression.ShardingPrint());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -68,9 +68,9 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
|||
/// <returns></returns>
|
||||
protected abstract IQueryable<TEntity> CombineQueryable(IQueryable<TEntity> queryable, Expression secondExpression);
|
||||
|
||||
private IQueryable CreateAsyncExecuteQueryable<TResult>(RouteResult routeResult)
|
||||
private IQueryable CreateAsyncExecuteQueryable<TResult>(string dsname,TableRouteResult tableRouteResult)
|
||||
{
|
||||
var shardingDbContext = _mergeContext.CreateDbContext(routeResult);
|
||||
var shardingDbContext = _mergeContext.CreateDbContext(dsname,tableRouteResult);
|
||||
_parllelDbbContexts.Add(shardingDbContext);
|
||||
var newQueryable = (IQueryable<TEntity>) GetStreamMergeContext().GetReWriteQueryable()
|
||||
.ReplaceDbContextQueryable(shardingDbContext);
|
||||
|
@ -81,53 +81,36 @@ namespace ShardingCore.Sharding.StreamMergeEngines.Abstractions
|
|||
|
||||
public async Task<List<RouteQueryResult<TResult>>> ExecuteAsync<TResult>(Func<IQueryable, Task<TResult>> efQuery, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var tableResult = _mergeContext.RouteResults;
|
||||
var enumeratorTasks = tableResult.Select(routeResult =>
|
||||
var dataSourceRouteResult = _mergeContext.DataSourceRouteResult;
|
||||
|
||||
var enumeratorTasks = dataSourceRouteResult.IntersectDataSources.SelectMany(physicDataSource =>
|
||||
{
|
||||
return Task.Run(async () =>
|
||||
var dsname = physicDataSource.DSName;
|
||||
var tableRouteResults = _mergeContext.GetTableRouteResults(dsname);
|
||||
return tableRouteResults.Select(routeResult =>
|
||||
{
|
||||
try
|
||||
return Task.Run(async () =>
|
||||
{
|
||||
var asyncExecuteQueryable = CreateAsyncExecuteQueryable<TResult>(routeResult);
|
||||
var queryResult= await efQuery(asyncExecuteQueryable);
|
||||
return new RouteQueryResult<TResult>(routeResult, queryResult);
|
||||
//}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
try
|
||||
{
|
||||
var asyncExecuteQueryable = CreateAsyncExecuteQueryable<TResult>(dsname, routeResult);
|
||||
var queryResult = await efQuery(asyncExecuteQueryable);
|
||||
return new RouteQueryResult<TResult>(dsname, routeResult, queryResult);
|
||||
//}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
}).ToArray();
|
||||
|
||||
return (await Task.WhenAll(enumeratorTasks)).ToList();
|
||||
}
|
||||
|
||||
public List<TResult> Execute<TResult>(Func<IQueryable, TResult> efQuery, CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
var tableResult = _mergeContext.RouteResults;
|
||||
var enumeratorTasks = tableResult.Select(routeResult =>
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var asyncExecuteQueryable = CreateAsyncExecuteQueryable<TResult>(routeResult);
|
||||
var query = efQuery(asyncExecuteQueryable);
|
||||
return query;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
});
|
||||
}).ToArray();
|
||||
return Task.WhenAll(enumeratorTasks).GetAwaiter().GetResult().ToList();
|
||||
}
|
||||
|
||||
|
||||
public virtual IQueryable DoCombineQueryable<TResult>(IQueryable<TEntity> queryable)
|
||||
{
|
||||
return queryable;
|
||||
|
|
|
@ -3,10 +3,6 @@ using System.Collections;
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
#if EFCORE2
|
||||
using Microsoft.EntityFrameworkCore.Extensions.Internal;
|
||||
#endif
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines
|
||||
{
|
||||
/*
|
||||
|
@ -25,21 +21,11 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
}
|
||||
|
||||
|
||||
#if !EFCORE2
|
||||
public IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return new EnumeratorShardingQueryExecutor<T>(_mergeContext).ExecuteAsync(cancellationToken)
|
||||
.GetAsyncEnumerator(cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
IAsyncEnumerator<T> IAsyncEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
return ((IAsyncEnumerable<T>)new EnumeratorShardingQueryExecutor<T>(_mergeContext).ExecuteAsync())
|
||||
.GetEnumerator();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
{
|
||||
foreach (var routeQueryResult in result)
|
||||
{
|
||||
_shardingPageManager.Current.RouteQueryResults.Add(new RouteQueryResult<long>(routeQueryResult.RouteResult, routeQueryResult.QueryResult));
|
||||
_shardingPageManager.Current.RouteQueryResults.Add(new RouteQueryResult<long>(routeQueryResult.TableRouteResult, routeQueryResult.QueryResult));
|
||||
}
|
||||
}
|
||||
return result.Sum(o=>o.QueryResult);
|
||||
|
|
|
@ -10,9 +10,6 @@ using ShardingCore.Exceptions;
|
|||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Sharding.Enumerators;
|
||||
using ShardingCore.Sharding.Enumerators.StreamMergeAsync;
|
||||
#if EFCORE2
|
||||
using Microsoft.EntityFrameworkCore.Extensions.Internal;
|
||||
#endif
|
||||
|
||||
namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.Abstractions
|
||||
{
|
||||
|
@ -60,16 +57,9 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
}
|
||||
public async Task<IAsyncEnumerator<TEntity>> DoGetAsyncEnumerator(IQueryable<TEntity> newQueryable)
|
||||
{
|
||||
#if !EFCORE2
|
||||
var enumator = newQueryable.AsAsyncEnumerable().GetAsyncEnumerator();
|
||||
await enumator.MoveNextAsync();
|
||||
return enumator;
|
||||
#endif
|
||||
#if EFCORE2
|
||||
var enumator = newQueryable.AsAsyncEnumerable().GetEnumerator();
|
||||
await enumator.MoveNext();
|
||||
return enumator;
|
||||
#endif
|
||||
}
|
||||
public IEnumerator<TEntity> DoGetEnumerator(IQueryable<TEntity> newQueryable)
|
||||
{
|
||||
|
@ -77,11 +67,11 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
enumator.MoveNext();
|
||||
return enumator;
|
||||
}
|
||||
// public virtual IQueryable<TEntity> CreateAsyncExecuteQueryable(RouteResult routeResult)
|
||||
// public virtual IQueryable<TEntity> CreateAsyncExecuteQueryable(TableRouteResult tableRouteResult)
|
||||
// {
|
||||
// var shardingDbContext = StreamMergeContext.CreateDbContext(routeResult);
|
||||
// var shardingDbContext = StreamMergeContext.CreateDbContext(tableRouteResult);
|
||||
// var useOriginal = StreamMergeContext > 1;
|
||||
// DbContextQueryStore.TryAdd(routeResult,shardingDbContext);
|
||||
// DbContextQueryStore.TryAdd(tableRouteResult,shardingDbContext);
|
||||
// var newQueryable = (IQueryable<TEntity>)(useOriginal ? StreamMergeContext.GetReWriteQueryable() : StreamMergeContext.GetOriginalQueryable())
|
||||
// .ReplaceDbContextQueryable(shardingDbContext);
|
||||
// return newQueryable;
|
||||
|
|
|
@ -21,32 +21,22 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
public abstract class AbstractEnumeratorStreamMergeEngine<TEntity>:IEnumeratorStreamMergeEngine<TEntity>
|
||||
{
|
||||
public StreamMergeContext<TEntity> StreamMergeContext { get; }
|
||||
public ConcurrentDictionary<RouteResult,DbContext> DbContextQueryStore { get; }
|
||||
public ConcurrentDictionary<TableRouteResult,DbContext> DbContextQueryStore { get; }
|
||||
|
||||
public AbstractEnumeratorStreamMergeEngine(StreamMergeContext<TEntity> streamMergeContext)
|
||||
{
|
||||
StreamMergeContext = streamMergeContext;
|
||||
DbContextQueryStore = new ConcurrentDictionary<RouteResult, DbContext>();
|
||||
DbContextQueryStore = new ConcurrentDictionary<TableRouteResult, DbContext>();
|
||||
}
|
||||
|
||||
public abstract IStreamMergeAsyncEnumerator<TEntity> GetShardingAsyncEnumerator(bool async,
|
||||
CancellationToken cancellationToken = new CancellationToken());
|
||||
|
||||
#if !EFCORE2
|
||||
public IAsyncEnumerator<TEntity> GetAsyncEnumerator(
|
||||
CancellationToken cancellationToken = new CancellationToken())
|
||||
{
|
||||
return GetShardingAsyncEnumerator(true,cancellationToken);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EFCORE2
|
||||
IAsyncEnumerator<TEntity> IAsyncEnumerable<TEntity>.GetEnumerator()
|
||||
{
|
||||
return GetShardingAsyncEnumerator(true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public IEnumerator<TEntity> GetEnumerator()
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
currentRealTake = currentTake.Value-currentRealTake;
|
||||
}
|
||||
}
|
||||
var sequenceResult = new SequenceResult(currentRealSkip, currentRealTake, routeQueryResult.RouteResult);
|
||||
var sequenceResult = new SequenceResult(currentRealSkip, currentRealTake, routeQueryResult);
|
||||
routeResults.Add(sequenceResult);
|
||||
|
||||
if (needBreak)
|
||||
|
@ -91,16 +91,18 @@ namespace ShardingCore.Sharding.StreamMergeEngines.EnumeratorStreamMergeEngines.
|
|||
}
|
||||
public class SequenceResult
|
||||
{
|
||||
public SequenceResult(long skip, long take, RouteResult routeResult)
|
||||
public SequenceResult(long skip, long take,RouteQueryResult<long> routeQueryResult)
|
||||
{
|
||||
Skip = (int)skip;
|
||||
Take = (int)take;
|
||||
RouteResult = routeResult;
|
||||
DSName = routeQueryResult.DSName;
|
||||
TableRouteResult = routeQueryResult.TableRouteResult;
|
||||
}
|
||||
|
||||
public int Skip { get; }
|
||||
public int Take { get; }
|
||||
|
||||
public RouteResult RouteResult { get; }
|
||||
public string DSName { get; }
|
||||
public TableRouteResult TableRouteResult { get; }
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue