修复queryable下的orderby

This commit is contained in:
xuejiaming 2022-01-09 13:03:29 +08:00
parent 691fbab8a3
commit 81c3e21f43
17 changed files with 407 additions and 64 deletions

View File

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

View File

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

View File

@ -32,5 +32,6 @@ namespace Sample.MultiConfig.Controllers
var listAsync = await _multiConfigDbContext.Set<Order>().ToListAsync();
return Ok(listAsync);
}
}
}

View File

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

View File

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

View File

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

View File

@ -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>
/// 如果数据库不存在就创建并且创建表除了分表的

View File

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

View File

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

View File

@ -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>
/// 路由到具体的物理数据源

View File

@ -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();
//Ìí¼ÓÊý¾ÝÔ´

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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