修复内存排序下没有使用shardingcomparer的纠正
This commit is contained in:
parent
ac83780b67
commit
32e647a18d
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Threading.Tasks;
|
||||
using Sample.SqlServerShardingTable.Entities;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.TableRoutes.Abstractions;
|
||||
using ShardingCore.Helpers;
|
||||
|
||||
namespace Sample.SqlServerShardingTable.VirtualRoutes
|
||||
{
|
||||
public class OrderHashRangeVirtualTableRoute:AbstractShardingOperatorVirtualTableRoute<Order,string>
|
||||
{
|
||||
protected override string ConvertToShardingKey(object shardingKey)
|
||||
{
|
||||
return shardingKey.ToString();
|
||||
}
|
||||
|
||||
public override string ShardingKeyToTail(object shardingKey)
|
||||
{
|
||||
var stringHashCode = ShardingCoreHelper.GetStringHashCode("123");
|
||||
var hashCode = stringHashCode % 10000;
|
||||
if (hashCode >= 0 && hashCode <= 3000)
|
||||
{
|
||||
return "A";
|
||||
}
|
||||
else if (hashCode >= 3001 && hashCode <= 6000)
|
||||
{
|
||||
return "B";
|
||||
}
|
||||
else if (hashCode >= 6001 && hashCode <= 10000)
|
||||
{
|
||||
return "C";
|
||||
}
|
||||
else
|
||||
throw new InvalidOperationException($"cant calc hash route hash code:[{stringHashCode}]");
|
||||
}
|
||||
|
||||
public override List<string> GetAllTails()
|
||||
{
|
||||
return new List<string>()
|
||||
{
|
||||
"A", "B", "C"
|
||||
};
|
||||
}
|
||||
|
||||
protected override Expression<Func<string, bool>> GetRouteToFilter(string shardingKey, ShardingOperatorEnum shardingOperator)
|
||||
{
|
||||
//因为hash路由仅支持等于所以仅仅只需要写等于的情况
|
||||
var t = ShardingKeyToTail(shardingKey);
|
||||
switch (shardingOperator)
|
||||
{
|
||||
case ShardingOperatorEnum.Equal: return tail => tail == t;
|
||||
default:
|
||||
{
|
||||
return tail => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ using ShardingCore.Sharding.Abstractions;
|
|||
namespace ShardingCore.Core.EntityMetadatas
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认分片对象原数据管理者实现
|
||||
/// 默认分片对象元数据管理者实现
|
||||
/// </summary>
|
||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||
public class DefaultEntityMetadataManager<TShardingDbContext> : IEntityMetadataManager<TShardingDbContext> where TShardingDbContext : DbContext, IShardingDbContext
|
||||
|
|
|
@ -70,16 +70,16 @@ namespace ShardingCore.Extensions
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 切换数据源,保留原数据源中的Expression
|
||||
/// 切换数据源,保留原始数据源中的Expression
|
||||
/// </summary>
|
||||
/// <param name="source">原数据源</param>
|
||||
/// <param name="newSource">新数据源</param>
|
||||
/// <param name="source">元数据源</param>
|
||||
/// <param name="dbContext">新数据源</param>
|
||||
/// <returns></returns>
|
||||
internal static IQueryable ReplaceDbContextQueryable(this IQueryable source, DbContext dbContext)
|
||||
{
|
||||
DbContextReplaceQueryableVisitor replaceQueryableVisitor = new DbContextReplaceQueryableVisitor(dbContext);
|
||||
var newExpre = replaceQueryableVisitor.Visit(source.Expression);
|
||||
return replaceQueryableVisitor.Source.Provider.CreateQuery(newExpre);
|
||||
var newExpression = replaceQueryableVisitor.Visit(source.Expression);
|
||||
return replaceQueryableVisitor.Source.Provider.CreateQuery(newExpression);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,8 @@ using System.Linq;
|
|||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using ShardingCore.Core.Internal.Visitors;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
using ShardingCore.Sharding.Internals;
|
||||
|
||||
namespace ShardingCore.Extensions
|
||||
{
|
||||
|
@ -45,40 +47,51 @@ namespace ShardingCore.Extensions
|
|||
return Expression.Lambda(propertyAccess, parameter);
|
||||
}
|
||||
|
||||
private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName)
|
||||
private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName,IShardingComparer shardingComparer=null)
|
||||
{
|
||||
Type type = typeof(TEntity);
|
||||
Type selectorResultType;
|
||||
LambdaExpression selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
|
||||
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
|
||||
new Type[] {type, selectorResultType},
|
||||
source.Expression, Expression.Quote(selector));
|
||||
MethodCallExpression resultExp;
|
||||
if (shardingComparer == null)
|
||||
{
|
||||
resultExp = Expression.Call(typeof(Queryable), methodName,
|
||||
new Type[] { type, selectorResultType },
|
||||
source.Expression, Expression.Quote(selector));
|
||||
}
|
||||
else
|
||||
{
|
||||
var comparer = Activator.CreateInstance(typeof(InMemoryShardingComparer<>).GetGenericType0(selectorResultType), shardingComparer);
|
||||
resultExp = Expression.Call(typeof(Queryable), methodName,
|
||||
new Type[] { type, selectorResultType },
|
||||
source.Expression, Expression.Quote(selector),Expression.Constant(comparer));
|
||||
}
|
||||
return resultExp;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string fieldName)
|
||||
internal static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string fieldName, IShardingComparer shardingComparer = null)
|
||||
{
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.OrderBy), fieldName);
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.OrderBy), fieldName, shardingComparer);
|
||||
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
|
||||
}
|
||||
|
||||
internal static IOrderedQueryable<TEntity> OrderByDescending<TEntity>(this IQueryable<TEntity> source, string fieldName)
|
||||
internal static IOrderedQueryable<TEntity> OrderByDescending<TEntity>(this IQueryable<TEntity> source, string fieldName, IShardingComparer shardingComparer = null)
|
||||
{
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.OrderByDescending), fieldName);
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.OrderByDescending), fieldName, shardingComparer);
|
||||
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
|
||||
}
|
||||
|
||||
internal static IOrderedQueryable<TEntity> ThenBy<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName)
|
||||
internal static IOrderedQueryable<TEntity> ThenBy<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName, IShardingComparer shardingComparer = null)
|
||||
{
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.ThenBy), fieldName);
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.ThenBy), fieldName, shardingComparer);
|
||||
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
|
||||
}
|
||||
|
||||
internal static IOrderedQueryable<TEntity> ThenByDescending<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName)
|
||||
internal static IOrderedQueryable<TEntity> ThenByDescending<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName, IShardingComparer shardingComparer = null)
|
||||
{
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.ThenByDescending), fieldName);
|
||||
MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, nameof(Queryable.ThenByDescending), fieldName, shardingComparer);
|
||||
return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -86,9 +99,10 @@ namespace ShardingCore.Extensions
|
|||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="sortExpression">"child.name asc,child.age desc"</param>
|
||||
/// <param name="shardingComparer"></param>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal static IOrderedQueryable<TEntity> OrderWithExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression)
|
||||
internal static IOrderedQueryable<TEntity> OrderWithExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression, IShardingComparer shardingComparer = null)
|
||||
{
|
||||
String[] orderFields = sortExpression.Split(',');
|
||||
IOrderedQueryable<TEntity> result = null;
|
||||
|
@ -99,17 +113,17 @@ namespace ShardingCore.Extensions
|
|||
Boolean sortDescending = (expressionPart.Length == 2) && (expressionPart[1].Equals("DESC", StringComparison.OrdinalIgnoreCase));
|
||||
if (sortDescending)
|
||||
{
|
||||
result = currentFieldIndex == 0 ? source.OrderByDescending(sortField) : result.ThenByDescending(sortField);
|
||||
result = currentFieldIndex == 0 ? source.OrderByDescending(sortField,shardingComparer) : result.ThenByDescending(sortField, shardingComparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = currentFieldIndex == 0 ? source.OrderBy(sortField) : result.ThenBy(sortField);
|
||||
result = currentFieldIndex == 0 ? source.OrderBy(sortField, shardingComparer) : result.ThenBy(sortField, shardingComparer);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
internal static IOrderedQueryable<TEntity> OrderWithExpression<TEntity>(this IQueryable<TEntity> source, IEnumerable<PropertyOrder> propertyOrders)
|
||||
internal static IOrderedQueryable<TEntity> OrderWithExpression<TEntity>(this IQueryable<TEntity> source, IEnumerable<PropertyOrder> propertyOrders, IShardingComparer shardingComparer = null)
|
||||
{
|
||||
IOrderedQueryable<TEntity> result = null;
|
||||
var currentIndex = 0;
|
||||
|
@ -118,11 +132,11 @@ namespace ShardingCore.Extensions
|
|||
String sortField = propertyOrder.PropertyExpression;
|
||||
if (propertyOrder.IsAsc)
|
||||
{
|
||||
result = currentIndex == 0 ? source.OrderBy(sortField) : result.ThenBy(sortField);
|
||||
result = currentIndex == 0 ? source.OrderBy(sortField, shardingComparer) : result.ThenBy(sortField, shardingComparer);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = currentIndex == 0 ? source.OrderByDescending(sortField) : result.ThenByDescending(sortField);
|
||||
result = currentIndex == 0 ? source.OrderByDescending(sortField, shardingComparer) : result.ThenByDescending(sortField, shardingComparer);
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
|
|
|
@ -13,9 +13,9 @@ namespace ShardingCore.Sharding
|
|||
*/
|
||||
public class CSharpLanguageShardingComparer<TShardingDbContext>:IShardingComparer<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
|
||||
{
|
||||
public int Compare(IComparable a, IComparable b, bool asc)
|
||||
public int Compare(IComparable x, IComparable y, bool asc)
|
||||
{
|
||||
return a.SafeCompareToWith(b, asc);
|
||||
return x.SafeCompareToWith(y, asc);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ShardingCore.Sharding.Abstractions;
|
||||
|
||||
namespace ShardingCore.Sharding.Internals
|
||||
{
|
||||
public class InMemoryShardingComparer<T> : IComparer<T>
|
||||
{
|
||||
private readonly IShardingComparer _shardingComparer;
|
||||
|
||||
public InMemoryShardingComparer(IShardingComparer shardingComparer)
|
||||
{
|
||||
_shardingComparer = shardingComparer;
|
||||
}
|
||||
public int Compare(T x, T y)
|
||||
{
|
||||
if (x is IComparable a && y is IComparable b)
|
||||
return _shardingComparer.Compare(a, b, true);
|
||||
throw new NotImplementedException($"compare :[{typeof(T).FullName}] is not IComparable");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,7 +38,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (streamMergeContext.Orders.Any())
|
||||
return q.OrderWithExpression(streamMergeContext.Orders).First();
|
||||
return q.OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).First();
|
||||
|
||||
return q.First();
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (streamMergeContext.Orders.Any())
|
||||
return q.OrderWithExpression(streamMergeContext.Orders).FirstOrDefault();
|
||||
return q.OrderWithExpression(streamMergeContext.Orders,streamMergeContext.GetShardingComparer()).FirstOrDefault();
|
||||
|
||||
return q.FirstOrDefault();
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (streamMergeContext.Orders.Any())
|
||||
return q.OrderWithExpression(streamMergeContext.Orders).Last();
|
||||
return q.OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).Last();
|
||||
|
||||
return q.Last();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (streamMergeContext.Orders.Any())
|
||||
return q.OrderWithExpression(streamMergeContext.Orders).LastOrDefault();
|
||||
return q.OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).LastOrDefault();
|
||||
|
||||
return q.LastOrDefault();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (streamMergeContext.Orders.Any())
|
||||
return q.OrderWithExpression(streamMergeContext.Orders).Single();
|
||||
return q.OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).Single();
|
||||
|
||||
return q.Single();
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace ShardingCore.Sharding.StreamMergeEngines
|
|||
|
||||
var streamMergeContext = GetStreamMergeContext();
|
||||
if (streamMergeContext.Orders.Any())
|
||||
return q.OrderWithExpression(streamMergeContext.Orders).SingleOrDefault();
|
||||
return q.OrderWithExpression(streamMergeContext.Orders, streamMergeContext.GetShardingComparer()).SingleOrDefault();
|
||||
|
||||
return q.SingleOrDefault();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace ShardingCore.Core.Internal.StreamMerge.ReWrite
|
|||
if (selectProperties.IsNotEmpty())
|
||||
{
|
||||
var sort = string.Join(",",selectProperties.Select(o=>$"{o.PropertyName} asc"));
|
||||
reWriteQueryable = reWriteQueryable.OrderWithExpression(sort);
|
||||
reWriteQueryable = reWriteQueryable.OrderWithExpression(sort,null);
|
||||
var reWriteOrders = new List<PropertyOrder>(selectProperties.Count());
|
||||
foreach (var orderProperty in selectProperties)
|
||||
{
|
||||
|
|
|
@ -242,17 +242,18 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
//单个
|
||||
else
|
||||
{
|
||||
bool paramterAtLeft=false;
|
||||
//条件在右边
|
||||
bool conditionOnRight=false;
|
||||
object value = null;
|
||||
|
||||
if (IsShardingKey(binaryExpression.Left)&&IsConstantOrMember(binaryExpression.Right))
|
||||
{
|
||||
paramterAtLeft = true;
|
||||
conditionOnRight = true;
|
||||
value = GetShardingKeyValue(binaryExpression.Right);
|
||||
}
|
||||
else if (IsConstantOrMember(binaryExpression.Left) && IsShardingKey(binaryExpression.Right))
|
||||
{
|
||||
paramterAtLeft = false;
|
||||
conditionOnRight = false;
|
||||
value = GetShardingKeyValue(binaryExpression.Left);
|
||||
}
|
||||
else
|
||||
|
@ -260,10 +261,10 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
|
||||
var op = binaryExpression.NodeType switch
|
||||
{
|
||||
ExpressionType.GreaterThan => paramterAtLeft ? ShardingOperatorEnum.GreaterThan : ShardingOperatorEnum.LessThan,
|
||||
ExpressionType.GreaterThanOrEqual => paramterAtLeft ? ShardingOperatorEnum.GreaterThanOrEqual : ShardingOperatorEnum.LessThanOrEqual,
|
||||
ExpressionType.LessThan => paramterAtLeft ? ShardingOperatorEnum.LessThan : ShardingOperatorEnum.GreaterThan,
|
||||
ExpressionType.LessThanOrEqual => paramterAtLeft ? ShardingOperatorEnum.LessThanOrEqual : ShardingOperatorEnum.GreaterThanOrEqual,
|
||||
ExpressionType.GreaterThan => conditionOnRight ? ShardingOperatorEnum.GreaterThan : ShardingOperatorEnum.LessThan,
|
||||
ExpressionType.GreaterThanOrEqual => conditionOnRight ? ShardingOperatorEnum.GreaterThanOrEqual : ShardingOperatorEnum.LessThanOrEqual,
|
||||
ExpressionType.LessThan => conditionOnRight ? ShardingOperatorEnum.LessThan : ShardingOperatorEnum.GreaterThan,
|
||||
ExpressionType.LessThanOrEqual => conditionOnRight ? ShardingOperatorEnum.LessThanOrEqual : ShardingOperatorEnum.GreaterThanOrEqual,
|
||||
ExpressionType.Equal => ShardingOperatorEnum.Equal,
|
||||
ExpressionType.NotEqual => ShardingOperatorEnum.NotEqual,
|
||||
_ => ShardingOperatorEnum.UnKnown
|
||||
|
|
Loading…
Reference in New Issue