创建移除efcore2的分表基本

This commit is contained in:
xuejiaming 2021-09-17 13:16:52 +08:00
parent 8f665394ff
commit 1c1d6cf965
129 changed files with 1619 additions and 2144 deletions

View File

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

View File

@ -1,6 +1,5 @@
:start
::定义版本
set EFCORE2=2.2.0.20
set EFCORE3=3.2.0.20
set EFCORE5=5.2.0.20

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,6 +11,7 @@ namespace ShardingCore.Core.PhysicTables
*/
public interface IPhysicTable
{
string DSName { get;}
/// <summary>
/// 表全称
/// </summary>

View File

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

View File

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

View File

@ -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; } = "_";
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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就是表示不开启分页配置

View File

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

View File

@ -1,4 +1,4 @@
namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
{
/*
* @Author: xjm

View File

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

View File

@ -1,4 +1,4 @@
namespace ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions
namespace ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions
{
/*
* @Author: xjm

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore;
using ShardingCore.DbContexts.Abstractions;
using System;
using System.Collections.Generic;
using ShardingCore.Core.VirtualRoutes.TableRoutes;

View File

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

View File

@ -15,6 +15,6 @@ namespace ShardingCore.Sharding.Abstractions
public interface IConnectionStringManager
{
Type ShardingDbContextType { get; }
string GetConnectionString(IShardingDbContext shardingDbContext);
string GetConnectionString(string dsName,IShardingDbContext shardingDbContext);
}
}

View File

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

View File

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

View File

@ -17,6 +17,6 @@ namespace ShardingCore.Sharding.Abstractions
int ReadWritePriority { get; set; }
bool ReadWriteSupport { get; set; }
ReadConnStringGetStrategyEnum GetReadConnStringGetStrategy();
string GetWriteConnectionString();
string GetWriteConnectionString(string dsName);
}
}

View File

@ -1,4 +1,4 @@
using ShardingCore.Core.VirtualRoutes.RouteTails.Abstractions;
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
namespace ShardingCore.Sharding.Abstractions
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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