修复queryable下的orderby
This commit is contained in:
parent
691fbab8a3
commit
81c3e21f43
|
@ -1,9 +1,9 @@
|
|||
:start
|
||||
::定义版本
|
||||
set EFCORE2=2.4.0.01-preview4
|
||||
set EFCORE3=3.4.0.01-preview4
|
||||
set EFCORE5=5.4.0.01-preview4
|
||||
set EFCORE6=6.4.0.01-preview4
|
||||
set EFCORE2=2.4.0.01-rc2
|
||||
set EFCORE3=3.4.0.01-rc2
|
||||
set EFCORE5=5.4.0.01-rc2
|
||||
set EFCORE6=6.4.0.01-rc2
|
||||
|
||||
::删除所有bin与obj下的文件
|
||||
@echo off
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
using System.Data.Common;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
|
||||
namespace Sample.MultiConfig.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class CommonController : ControllerBase
|
||||
{
|
||||
private readonly IVirtualDataSourceManager<MultiConfigDbContext> _virtualDataSourceManager;
|
||||
|
||||
public CommonController(IVirtualDataSourceManager<MultiConfigDbContext> virtualDataSourceManager)
|
||||
{
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
}
|
||||
public async Task<IActionResult> DynamicAdd(string configId)
|
||||
{
|
||||
var flag = DynamicDataSourceHelper.DynamicAppendVirtualDataSource(new MySqlConfigurationParam(configId));
|
||||
return Ok(flag?"成功":"失败");
|
||||
}
|
||||
}
|
||||
|
||||
public class MySqlConfigurationParam : AbstractVirtualDataSourceConfigurationParams<MultiConfigDbContext>
|
||||
{
|
||||
public override string ConfigId { get; }
|
||||
public override int Priority { get; }
|
||||
public override string DefaultDataSourceName { get; }
|
||||
public override string DefaultConnectionString { get; }
|
||||
public override IDictionary<string, IEnumerable<string>> ReadWriteSeparationConfigs { get; }
|
||||
public override ReadStrategyEnum? ReadStrategy { get; }
|
||||
public override bool? ReadWriteDefaultEnable { get; }
|
||||
public override int? ReadWriteDefaultPriority { get; }
|
||||
public override ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
|
||||
public MySqlConfigurationParam(string configId)
|
||||
{
|
||||
ConfigId = configId;
|
||||
DefaultDataSourceName = "ds0";
|
||||
DefaultConnectionString = $"server=127.0.0.1;port=3306;database=MultiConfigSharding{configId};userid=root;password=L6yBtV6qNENrwBy7;";
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
dbContextOptionsBuilder.UseMySql(connectionString,new MySqlServerVersion(new Version()));
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
|
||||
public override DbContextOptionsBuilder UseDbContextOptionsBuilder(DbConnection dbConnection,
|
||||
DbContextOptionsBuilder dbContextOptionsBuilder)
|
||||
{
|
||||
dbContextOptionsBuilder.UseMySql(dbConnection, new MySqlServerVersion(new Version()));
|
||||
return dbContextOptionsBuilder;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,5 +32,6 @@ namespace Sample.MultiConfig.Controllers
|
|||
var listAsync = await _multiConfigDbContext.Set<Order>().ToListAsync();
|
||||
return Ok(listAsync);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
"profiles": {
|
||||
"Sample.MultiConfig": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "weatherforecast",
|
||||
"applicationUrl": "http://localhost:5138",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"applicationUrl": "http://localhost:5138",
|
||||
"dotnetRunMessages": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,9 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Sample.SqlServerShardingTable.Entities;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Extensions;
|
||||
using ShardingCore.Helpers;
|
||||
|
||||
namespace Sample.SqlServerShardingTable.Controllers
|
||||
{
|
||||
|
@ -12,10 +15,12 @@ namespace Sample.SqlServerShardingTable.Controllers
|
|||
public class TestController : ControllerBase
|
||||
{
|
||||
private readonly MyDbContext _myDbContext;
|
||||
private readonly IVirtualDataSourceManager<MyDbContext> _virtualDataSourceManager;
|
||||
|
||||
public TestController(MyDbContext myDbContext)
|
||||
public TestController(MyDbContext myDbContext,IVirtualDataSourceManager<MyDbContext> virtualDataSourceManager)
|
||||
{
|
||||
_myDbContext = myDbContext;
|
||||
_virtualDataSourceManager = virtualDataSourceManager;
|
||||
}
|
||||
public async Task<IActionResult> Query()
|
||||
{
|
||||
|
@ -105,5 +110,20 @@ namespace Sample.SqlServerShardingTable.Controllers
|
|||
var i = await _myDbContext.SaveChangesAsync();
|
||||
return Ok(i);
|
||||
}
|
||||
|
||||
public async Task<IActionResult> DynamicReadWrite()
|
||||
{
|
||||
DynamicShardingHelper.DynamicAppendReadWriteConnectionString<MyDbContext>("a","ds0", "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB1;Integrated Security=True;");
|
||||
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1").FirstOrDefaultAsync();
|
||||
|
||||
return Ok(sysUser);
|
||||
}
|
||||
public async Task<IActionResult> Read()
|
||||
{
|
||||
_myDbContext.ReadWriteSeparationWriteOnly();
|
||||
var sysUser = await _myDbContext.Set<SysUser>().Where(o => o.Id == "1").FirstOrDefaultAsync();
|
||||
|
||||
return Ok(sysUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,12 +98,12 @@ namespace Sample.SqlServerShardingTable
|
|||
{
|
||||
return new Dictionary<string, IEnumerable<string>>()
|
||||
{
|
||||
{
|
||||
"ds0", new List<string>()
|
||||
{
|
||||
"Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;"
|
||||
}
|
||||
}
|
||||
//{
|
||||
// "ds0", new List<string>()
|
||||
// {
|
||||
// "Data Source=localhost;Initial Catalog=EFCoreShardingTableDB;Integrated Security=True;"
|
||||
// }
|
||||
//}
|
||||
};
|
||||
}, ReadStrategyEnum.Loop, defaultEnable: true);
|
||||
op.ReplaceTableEnsureManager(sp=>new SqlServerTableEnsureManager<MyDbContext>());
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace ShardingCore.Core.ShardingConfigurations
|
|||
{
|
||||
private readonly IDictionary<Type, Type> _virtualDataSourceRoutes = new Dictionary<Type, Type>();
|
||||
private readonly IDictionary<Type, Type> _virtualTableRoutes = new Dictionary<Type, Type>();
|
||||
public readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
|
||||
private readonly ISet<ParallelTableGroupNode> _parallelTables = new HashSet<ParallelTableGroupNode>();
|
||||
|
||||
/// <summary>
|
||||
/// 如果数据库不存在就创建并且创建表除了分表的
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
|
@ -10,7 +11,9 @@ using ShardingCore.Extensions;
|
|||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ParallelTables;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ShardingComparision;
|
||||
using ShardingCore.Sharding.ShardingComparision.Abstractions;
|
||||
using ShardingCore.TableExists;
|
||||
using ShardingCore.TableExists.Abstractions;
|
||||
|
||||
namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
||||
|
@ -20,18 +23,21 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
{
|
||||
public abstract string ConfigId { get; }
|
||||
public abstract int Priority { get; }
|
||||
public abstract int MaxQueryConnectionsLimit { get; }
|
||||
public abstract ConnectionModeEnum ConnectionMode { get; }
|
||||
public virtual int MaxQueryConnectionsLimit { get; } = Environment.ProcessorCount;
|
||||
public virtual ConnectionModeEnum ConnectionMode { get; } = ConnectionModeEnum.SYSTEM_AUTO;
|
||||
public abstract string DefaultDataSourceName { get; }
|
||||
public abstract string DefaultConnectionString { get; }
|
||||
public abstract IDictionary<string, string> ExtraDataSources { get; }
|
||||
public virtual IDictionary<string, string> ExtraDataSources { get; }=new ConcurrentDictionary<string, string>();
|
||||
public abstract IDictionary<string, IEnumerable<string>> ReadWriteSeparationConfigs { get; }
|
||||
public abstract ReadStrategyEnum? ReadStrategy { get; }
|
||||
public abstract bool? ReadWriteDefaultEnable { get; }
|
||||
public abstract int? ReadWriteDefaultPriority { get; }
|
||||
public abstract ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
public abstract IShardingComparer ShardingComparer { get; }
|
||||
public abstract ITableEnsureManager TableEnsureManager { get; }
|
||||
public virtual IShardingComparer ShardingComparer { get; } = new CSharpLanguageShardingComparer();
|
||||
|
||||
public virtual ITableEnsureManager TableEnsureManager { get; } =
|
||||
new EmptyTableEnsureManager<TShardingDbContext>();
|
||||
|
||||
|
||||
|
||||
public abstract DbContextOptionsBuilder UseDbContextOptionsBuilder(string connectionString,
|
||||
|
|
|
@ -18,6 +18,9 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// 优先级
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
/// <summary>
|
||||
/// 不能小于等于0 should greater than or equal zero
|
||||
/// </summary>
|
||||
int MaxQueryConnectionsLimit { get; }
|
||||
ConnectionModeEnum ConnectionMode { get; }
|
||||
|
||||
|
@ -29,7 +32,13 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// 默认数据源链接字符串
|
||||
/// </summary>
|
||||
string DefaultConnectionString { get; }
|
||||
/// <summary>
|
||||
/// 不能为空null,should not null
|
||||
/// </summary>
|
||||
IDictionary<string,string> ExtraDataSources { get; }
|
||||
/// <summary>
|
||||
/// null表示不启用读写分离,if null mean not enable read write
|
||||
/// </summary>
|
||||
IDictionary<string, IEnumerable<string>> ReadWriteSeparationConfigs { get; }
|
||||
|
||||
ReadStrategyEnum? ReadStrategy { get; }
|
||||
|
@ -39,6 +48,9 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions
|
|||
/// 读写分离链接字符串获取
|
||||
/// </summary>
|
||||
ReadConnStringGetStrategyEnum? ReadConnStringGetStrategy { get; }
|
||||
/// <summary>
|
||||
/// 不能为空 should not null
|
||||
/// </summary>
|
||||
IShardingComparer ShardingComparer { get; }
|
||||
ITableEnsureManager TableEnsureManager { get; }
|
||||
/// <summary>
|
||||
|
|
|
@ -22,17 +22,39 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
public interface IVirtualDataSource
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 配置id
|
||||
/// </summary>
|
||||
string ConfigId { get; }
|
||||
/// <summary>
|
||||
/// 当前配置的优先级
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
/// <summary>
|
||||
/// 数据源配置
|
||||
/// </summary>
|
||||
IVirtualDataSourceConfigurationParams ConfigurationParams { get; }
|
||||
/// <summary>
|
||||
/// 链接字符串管理
|
||||
/// </summary>
|
||||
IConnectionStringManager ConnectionStringManager { get; }
|
||||
/// <summary>
|
||||
/// 是否启用了读写分离
|
||||
/// </summary>
|
||||
bool UseReadWriteSeparation { get; }
|
||||
/// <summary>
|
||||
/// 默认的数据源名称
|
||||
/// </summary>
|
||||
string DefaultDataSourceName { get; }
|
||||
/// <summary>
|
||||
/// 默认连接字符串
|
||||
/// </summary>
|
||||
string DefaultConnectionString { get;}
|
||||
/// <summary>
|
||||
/// 获取路由
|
||||
/// </summary>
|
||||
/// <param name="entityType"></param>
|
||||
/// <returns></returns>
|
||||
IVirtualDataSourceRoute GetRoute(Type entityType);
|
||||
/// <summary>
|
||||
/// 路由到具体的物理数据源
|
||||
|
|
|
@ -46,6 +46,11 @@ namespace ShardingCore.Core.VirtualDatabase.VirtualDataSources
|
|||
|
||||
public VirtualDataSource(IEntityMetadataManager<TShardingDbContext> entityMetadataManager, IVirtualDataSourceRouteManager<TShardingDbContext> dataSourceRouteManager, IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
{
|
||||
Check.NotNull(configurationParams, nameof(configurationParams));
|
||||
Check.NotNull(configurationParams.ExtraDataSources, nameof(configurationParams.ExtraDataSources));
|
||||
Check.NotNull(configurationParams.ShardingComparer, nameof(configurationParams.ShardingComparer));
|
||||
if(configurationParams.MaxQueryConnectionsLimit<=0)
|
||||
throw new ArgumentOutOfRangeException(nameof(configurationParams.MaxQueryConnectionsLimit));
|
||||
ConfigurationParams = configurationParams;
|
||||
_physicDataSourcePool = new PhysicDataSourcePool();
|
||||
//Ìí¼ÓÊý¾ÝÔ´
|
||||
|
|
|
@ -4,9 +4,13 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
namespace ShardingCore.DynamicDataSources
|
||||
{
|
||||
[Obsolete("plz use DynamicShardingHelper")]
|
||||
public class DynamicDataSourceHelper
|
||||
{
|
||||
private DynamicDataSourceHelper()
|
||||
|
@ -28,7 +32,7 @@ namespace ShardingCore.DynamicDataSources
|
|||
defaultDataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName, connectionString, false);
|
||||
}
|
||||
|
||||
public static void DynamicAppendVirtualDataSource<TShardingDbContext>(
|
||||
public static bool DynamicAppendVirtualDataSource<TShardingDbContext>(
|
||||
IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
|
@ -44,8 +48,46 @@ namespace ShardingCore.DynamicDataSources
|
|||
var connectionString = dataSource.Value;
|
||||
dataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName, connectionString, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态添加读写分离链接字符串
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="virtualDataSource"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <exception cref="ShardingCoreInvalidOperationException"></exception>
|
||||
public static void DynamicAppendReadWriteConnectionString<TShardingDbContext>(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName,
|
||||
string connectionString) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
if (virtualDataSource.ConnectionStringManager is IReadWriteAppendConnectionString
|
||||
readWriteAppendConnectionString)
|
||||
{
|
||||
readWriteAppendConnectionString.AddReadConnectionString(dataSourceName, connectionString);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{virtualDataSource.ConnectionStringManager.GetType()} cant support add read connection string");
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态添加读写分离链接字符串
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="configId"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
public static void DynamicAppendReadWriteConnectionString<TShardingDbContext>(string configId, string dataSourceName,
|
||||
string connectionString) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualDataSourceManager = ShardingContainer.GetRequiredVirtualDataSourceManager<TShardingDbContext>();
|
||||
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource(configId);
|
||||
DynamicAppendReadWriteConnectionString(virtualDataSource, dataSourceName, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.DynamicDataSources;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
namespace ShardingCore.Helpers
|
||||
{
|
||||
public class DynamicShardingHelper
|
||||
{
|
||||
private DynamicShardingHelper()
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(DynamicShardingHelper)} create instance");
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态添加虚拟数据源配置
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="configurationParams"></param>
|
||||
/// <returns></returns>
|
||||
public static bool DynamicAppendVirtualDataSourceConfig<TShardingDbContext>(
|
||||
IVirtualDataSourceConfigurationParams<TShardingDbContext> configurationParams)
|
||||
where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualDataSourceManager = ShardingContainer.GetRequiredVirtualDataSourceManager<TShardingDbContext>();
|
||||
if (virtualDataSourceManager.AddVirtualDataSource(configurationParams))
|
||||
{
|
||||
virtualDataSourceManager.SetDefaultIfMultiConfiguration();
|
||||
var dataSourceInitializer = ShardingContainer.GetService<IDataSourceInitializer<TShardingDbContext>>();
|
||||
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource(configurationParams.ConfigId);
|
||||
foreach (var dataSource in virtualDataSource.GetDataSources())
|
||||
{
|
||||
var dataSourceName = dataSource.Key;
|
||||
var connectionString = dataSource.Value;
|
||||
dataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName, connectionString, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态添加数据源
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="virtualDataSource"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
public static void DynamicAppendDataSource<TShardingDbContext>(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName, string connectionString) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var defaultDataSourceInitializer = ShardingContainer.GetService<IDataSourceInitializer<TShardingDbContext>>();
|
||||
defaultDataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName, connectionString, false);
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态添加数据源
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="configId"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
public static void DynamicAppendDataSource<TShardingDbContext>(string configId, string dataSourceName, string connectionString) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var defaultDataSourceInitializer = ShardingContainer.GetService<IDataSourceInitializer<TShardingDbContext>>();
|
||||
var virtualDataSourceManager = ShardingContainer.GetService<IVirtualDataSourceManager<TShardingDbContext>>();
|
||||
|
||||
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource(configId);
|
||||
defaultDataSourceInitializer.InitConfigure(virtualDataSource, dataSourceName, connectionString, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态添加读写分离链接字符串
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="virtualDataSource"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
/// <exception cref="ShardingCoreInvalidOperationException"></exception>
|
||||
public static void DynamicAppendReadWriteConnectionString<TShardingDbContext>(IVirtualDataSource<TShardingDbContext> virtualDataSource, string dataSourceName,
|
||||
string connectionString) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
if (virtualDataSource.ConnectionStringManager is IReadWriteAppendConnectionString
|
||||
readWriteAppendConnectionString)
|
||||
{
|
||||
readWriteAppendConnectionString.AddReadConnectionString(dataSourceName, connectionString);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new ShardingCoreInvalidOperationException(
|
||||
$"{virtualDataSource.ConnectionStringManager.GetType()} cant support add read connection string");
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态添加读写分离链接字符串
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
/// <param name="configId"></param>
|
||||
/// <param name="dataSourceName"></param>
|
||||
/// <param name="connectionString"></param>
|
||||
public static void DynamicAppendReadWriteConnectionString<TShardingDbContext>(string configId, string dataSourceName,
|
||||
string connectionString) where TShardingDbContext : DbContext, IShardingDbContext
|
||||
{
|
||||
var virtualDataSourceManager = ShardingContainer.GetRequiredVirtualDataSourceManager<TShardingDbContext>();
|
||||
var virtualDataSource = virtualDataSourceManager.GetVirtualDataSource(configId);
|
||||
DynamicAppendReadWriteConnectionString(virtualDataSource, dataSourceName, connectionString);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Infrastructures;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
|
||||
|
@ -13,6 +14,8 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations.Connectors.Abstractions
|
|||
{
|
||||
protected List<string> ConnectionStrings { get;}
|
||||
protected int Length { get; private set; }
|
||||
|
||||
private object slock = new object();
|
||||
//private readonly string _tempConnectionString;
|
||||
//private readonly OneByOneChecker _oneByOneChecker = new OneByOneChecker();
|
||||
|
||||
|
@ -39,9 +42,19 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations.Connectors.Abstractions
|
|||
/// <returns></returns>
|
||||
public bool AddConnectionString(string connectionString)
|
||||
{
|
||||
ConnectionStrings.Add(connectionString);
|
||||
Length = ConnectionStrings.Count;
|
||||
return true;
|
||||
var acquired = Monitor.TryEnter(slock,TimeSpan.FromSeconds(3));
|
||||
if (!acquired)
|
||||
throw new ShardingCoreInvalidOperationException($"{nameof(AddConnectionString)} is busy");
|
||||
try
|
||||
{
|
||||
ConnectionStrings.Add(connectionString);
|
||||
Length = ConnectionStrings.Count;
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Exit(slock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
using System;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Exceptions;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.ReadWriteConfigurations.Abstractions;
|
||||
using System.Threading;
|
||||
|
||||
namespace ShardingCore.Sharding.ReadWriteConfigurations
|
||||
{
|
||||
|
@ -19,6 +15,7 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
new ConcurrentDictionary<string, IReadWriteConnector>();
|
||||
|
||||
private readonly IReadWriteConnectorFactory _readWriteConnectorFactory;
|
||||
private readonly ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim();
|
||||
public ReadWriteShardingConnectionStringResolver(IEnumerable<IReadWriteConnector> connectors, ReadStrategyEnum readStrategy)
|
||||
{
|
||||
_readStrategy = readStrategy;
|
||||
|
@ -53,9 +50,8 @@ namespace ShardingCore.Sharding.ReadWriteConfigurations
|
|||
dataSourceName, new List<string>()
|
||||
{
|
||||
connectionString
|
||||
});
|
||||
_connectors.TryAdd(dataSourceName, connector);
|
||||
return true;
|
||||
});
|
||||
return _connectors.TryAdd(dataSourceName, connector);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -9,19 +9,19 @@ using ShardingCore.Extensions;
|
|||
|
||||
namespace ShardingCore.Core.Internal.Visitors
|
||||
{
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 13 January 2021 11:04:50
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
internal class QueryableExtraDiscoverVisitor: ShardingExpressionVisitor
|
||||
/*
|
||||
* @Author: xjm
|
||||
* @Description:
|
||||
* @Date: Wednesday, 13 January 2021 11:04:50
|
||||
* @Email: 326308290@qq.com
|
||||
*/
|
||||
internal class QueryableExtraDiscoverVisitor : ShardingExpressionVisitor
|
||||
{
|
||||
private int? _skip;
|
||||
private int? _take;
|
||||
private LinkedList<PropertyOrder> _orders = new LinkedList<PropertyOrder>();
|
||||
private GroupByContext _groupByContext=new GroupByContext();
|
||||
private SelectContext _selectContext=new SelectContext();
|
||||
private GroupByContext _groupByContext = new GroupByContext();
|
||||
private SelectContext _selectContext = new SelectContext();
|
||||
|
||||
|
||||
public SelectContext GetSelectContext()
|
||||
|
@ -79,25 +79,29 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
if (HasTake())
|
||||
throw new ShardingCoreInvalidOperationException("more than one take found");
|
||||
_take = (int)GetFieldValue(node.Arguments[1]);
|
||||
}
|
||||
}
|
||||
else if (method.Name == nameof(Queryable.OrderBy) || method.Name == nameof(Queryable.OrderByDescending) || method.Name == nameof(Queryable.ThenBy) || method.Name == nameof(Queryable.ThenByDescending))
|
||||
{
|
||||
var expression=(((node.Arguments[1] as UnaryExpression).Operand as LambdaExpression).Body as MemberExpression);
|
||||
if (expression == null)
|
||||
throw new NotSupportedException("sharding order not support ");
|
||||
List<string> properties = new List<string>();
|
||||
GetProperty(properties, expression);
|
||||
if (!properties.Any())
|
||||
throw new NotSupportedException("sharding order only support property expression");
|
||||
properties.Reverse();
|
||||
var propertyExpression=string.Join(".", properties);
|
||||
_orders.AddFirst(new PropertyOrder(propertyExpression,method.Name == nameof(Queryable.OrderBy)||method.Name == nameof(Queryable.ThenBy)));
|
||||
if (typeof(IOrderedQueryable).IsAssignableFrom(node.Type))
|
||||
{
|
||||
var expression = (((node.Arguments[1] as UnaryExpression).Operand as LambdaExpression).Body as MemberExpression);
|
||||
if (expression == null)
|
||||
throw new NotSupportedException("sharding order not support ");
|
||||
List<string> properties = new List<string>();
|
||||
GetProperty(properties, expression);
|
||||
if (!properties.Any())
|
||||
throw new NotSupportedException("sharding order only support property expression");
|
||||
properties.Reverse();
|
||||
var propertyExpression = string.Join(".", properties);
|
||||
_orders.AddFirst(new PropertyOrder(propertyExpression, method.Name == nameof(Queryable.OrderBy) || method.Name == nameof(Queryable.ThenBy)));
|
||||
|
||||
}
|
||||
}
|
||||
else if (node.Method.Name == nameof(Queryable.GroupBy))
|
||||
{
|
||||
if (_groupByContext.GroupExpression == null)
|
||||
{
|
||||
var expression=(node.Arguments[1] as UnaryExpression).Operand as LambdaExpression;
|
||||
var expression = (node.Arguments[1] as UnaryExpression).Operand as LambdaExpression;
|
||||
if (expression == null)
|
||||
throw new NotSupportedException("sharding group not support ");
|
||||
_groupByContext.GroupExpression = expression;
|
||||
|
@ -107,7 +111,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
{
|
||||
if (_selectContext.SelectProperties.IsEmpty())
|
||||
{
|
||||
var expression=((node.Arguments[1] as UnaryExpression).Operand as LambdaExpression).Body as NewExpression;
|
||||
var expression = ((node.Arguments[1] as UnaryExpression).Operand as LambdaExpression).Body as NewExpression;
|
||||
if (expression != null)
|
||||
{
|
||||
var aggregateDiscoverVisitor = new QuerySelectDiscoverVisitor(_selectContext);
|
||||
|
@ -118,7 +122,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
|
||||
return base.VisitMethodCall(node);
|
||||
}
|
||||
private void GetProperty(List<string> properties,MemberExpression memberExpression)
|
||||
private void GetProperty(List<string> properties, MemberExpression memberExpression)
|
||||
{
|
||||
properties.Add(memberExpression.Member.Name);
|
||||
if (memberExpression.Expression is MemberExpression member)
|
||||
|
@ -127,7 +131,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -13,9 +13,11 @@ using ShardingCore.Core.VirtualDatabase.VirtualDataSources;
|
|||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.Abstractions;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualDataSources.PhysicDataSources;
|
||||
using ShardingCore.Core.VirtualDatabase.VirtualTables;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.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;
|
||||
using ShardingCore.Extensions.ShardingPageExtensions;
|
||||
|
@ -53,6 +55,7 @@ namespace ShardingCore.Test
|
|||
private readonly IShardingReadWriteManager _shardingReadWriteManager;
|
||||
private readonly IRouteTailFactory _routeTailFactory;
|
||||
private readonly IReadWriteConnectorFactory _readWriteConnectorFactory;
|
||||
private readonly ITableRouteRuleEngineFactory<ShardingDefaultDbContext> _tableRouteRuleEngineFactory;
|
||||
private readonly IShardingConnectionStringResolver _shardingConnectionStringResolver;
|
||||
|
||||
public ShardingTest(ShardingDefaultDbContext virtualDbContext, IShardingRouteManager shardingRouteManager, IConfiguration configuration,
|
||||
|
@ -61,7 +64,7 @@ namespace ShardingCore.Test
|
|||
IVirtualTableManager<ShardingDefaultDbContext> virtualTableManager,
|
||||
IShardingTableCreator<ShardingDefaultDbContext> shardingTableCreator,
|
||||
IShardingReadWriteManager shardingReadWriteManager,IRouteTailFactory routeTailFactory,
|
||||
IReadWriteConnectorFactory readWriteConnectorFactory)
|
||||
IReadWriteConnectorFactory readWriteConnectorFactory,ITableRouteRuleEngineFactory<ShardingDefaultDbContext> tableRouteRuleEngineFactory)
|
||||
{
|
||||
_virtualDbContext = virtualDbContext;
|
||||
_shardingRouteManager = shardingRouteManager;
|
||||
|
@ -74,6 +77,7 @@ namespace ShardingCore.Test
|
|||
_shardingReadWriteManager = shardingReadWriteManager;
|
||||
_routeTailFactory = routeTailFactory;
|
||||
_readWriteConnectorFactory = readWriteConnectorFactory;
|
||||
_tableRouteRuleEngineFactory = tableRouteRuleEngineFactory;
|
||||
var readWriteConnectors = _virtualDataSource.ConfigurationParams.ReadWriteSeparationConfigs.Select(o => readWriteConnectorFactory.CreateConnector(_virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault(), o.Key, o.Value));
|
||||
_shardingConnectionStringResolver = new ReadWriteShardingConnectionStringResolver(readWriteConnectors, _virtualDataSource.ConfigurationParams.ReadStrategy.GetValueOrDefault());
|
||||
}
|
||||
|
@ -716,6 +720,47 @@ namespace ShardingCore.Test
|
|||
Assert.Equal(1120000, group[0].MinSalary);
|
||||
Assert.Equal(1140000, group[0].MaxSalary);
|
||||
}
|
||||
//[Fact]
|
||||
//public async Task Group_Recently_Test()
|
||||
//{
|
||||
// //var list =(from us in _virtualDbContext.Set<SysUserSalary>().Where(o => ids.Contains(o.UserId))
|
||||
// // group us by new
|
||||
// // {
|
||||
// // UserId=us.UserId
|
||||
// // }
|
||||
// // into g
|
||||
// // select new
|
||||
// // {
|
||||
// // UserId=g.Key.UserId,
|
||||
// // DateOfMonth = g.Max(o=>o.DateOfMonth)
|
||||
// // }).ToList();
|
||||
// //var y = list;
|
||||
|
||||
// var ids = new List<string>(){ "200", "300" };
|
||||
// List<SysUserSalary> result = new List<SysUserSalary>(ids.Count);
|
||||
// var routeFilter = new List<SysUserSalary>().AsQueryable().Where(o => ids.Contains(o.UserId));
|
||||
// //»ñÈ¡µÄ·ÓÉʱ¼äµ¹Ðò
|
||||
// var tableRouteResults = _tableRouteRuleEngineFactory.Route(routeFilter)
|
||||
// .Select(o => o.ReplaceTables.First().Tail).OrderByDescending(o => o).ToList();
|
||||
// foreach (var tableRouteResult in tableRouteResults)
|
||||
// {
|
||||
// if(ids.IsEmpty())
|
||||
// break;
|
||||
// using (_shardingRouteManager.CreateScope())
|
||||
// {
|
||||
// _shardingRouteManager.Current.TryCreateOrAddMustTail<SysUserSalary>(tableRouteResult);
|
||||
// var queryable = _virtualDbContext.Set<SysUserSalary>().Where(o => ids.Contains(o.UserId))
|
||||
// .GroupBy(o => new { o.UserId }, i => i,
|
||||
// (i, u) => new {
|
||||
// Data = u.OrderByDescending(o => o.DateOfMonth).FirstOrDefault()
|
||||
// });
|
||||
// var r =await queryable.ToListAsync();
|
||||
// result.AddRange(r.Select(o=>o.Data));
|
||||
// var removeUserIds = result.Select(u => u.UserId).ToHashSet();
|
||||
// ids.RemoveAll(o => removeUserIds.Contains(o));
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task OrderCountTest()
|
||||
|
|
Loading…
Reference in New Issue