添加自定义排序实现

This commit is contained in:
xuejmnet 2021-10-31 16:11:39 +08:00
parent c1e1042e1a
commit e7ca85d25e
11 changed files with 142 additions and 13 deletions

View File

@ -30,6 +30,11 @@ namespace ShardingCore.DIExtensions
_shardingCoreConfigBuilder = shardingCoreConfigBuilder; _shardingCoreConfigBuilder = shardingCoreConfigBuilder;
} }
public ShardingCoreConfigEndBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
{
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
return this;
}
public IServiceCollection End() public IServiceCollection End()
{ {
var services = _shardingCoreConfigBuilder.Services; var services = _shardingCoreConfigBuilder.Services;
@ -50,6 +55,14 @@ namespace ShardingCore.DIExtensions
.AddSingleton<IShardingDbContextCreatorConfig, .AddSingleton<IShardingDbContextCreatorConfig,
DefaultShardingDbContextCreatorConfig<TShardingDbContext>>(sp => DefaultShardingDbContextCreatorConfig<TShardingDbContext>>(sp =>
new DefaultShardingDbContextCreatorConfig<TShardingDbContext>()); new DefaultShardingDbContextCreatorConfig<TShardingDbContext>());
if (_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparerFactory != null)
{
services.AddSingleton<IShardingComparer<TShardingDbContext>>(_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparerFactory);
}
else
{
services.AddSingleton<IShardingComparer<TShardingDbContext>, CSharpLanguageShardingComparer<TShardingDbContext>>();
}
if (!_shardingCoreConfigBuilder.ShardingConfigOption.UseReadWrite) if (!_shardingCoreConfigBuilder.ShardingConfigOption.UseReadWrite)
{ {
@ -94,6 +107,7 @@ namespace ShardingCore.DIExtensions
services.TryAddSingleton<IShardingReadWriteManager, ShardingReadWriteManager>(); services.TryAddSingleton<IShardingReadWriteManager, ShardingReadWriteManager>();
services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>(); services.AddSingleton<IShardingReadWriteAccessor, ShardingReadWriteAccessor<TShardingDbContext>>();
//foreach (var dataSourceKv in dataSources) //foreach (var dataSourceKv in dataSources)
//{ //{
// if (dataSourceKv.Key == _shardingCoreConfigBuilder.DefaultDataSourceName) // if (dataSourceKv.Key == _shardingCoreConfigBuilder.DefaultDataSourceName)

View File

@ -40,5 +40,10 @@ namespace ShardingCore.DIExtensions
} }
return new ShardingReadWriteSeparationBuilder<TShardingDbContext>(_shardingCoreConfigBuilder); return new ShardingReadWriteSeparationBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
} }
public ShardingDataBaseOrTableBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
{
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
return this;
}
} }
} }

View File

@ -36,5 +36,10 @@ namespace ShardingCore.DIExtensions
return new ShardingTableBuilder<TShardingDbContext>(_shardingCoreConfigBuilder); return new ShardingTableBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
} }
public ShardingDataSourceRouteBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
{
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
return this;
}
} }
} }

View File

@ -34,5 +34,10 @@ namespace ShardingCore.DIExtensions
_shardingCoreConfigBuilder.ShardingConfigOption.UseReadWriteConfiguration(readWriteSeparationConfigure,readStrategyEnum, defaultEnable,defaultPriority); _shardingCoreConfigBuilder.ShardingConfigOption.UseReadWriteConfiguration(readWriteSeparationConfigure,readStrategyEnum, defaultEnable,defaultPriority);
return new ShardingCoreConfigEndBuilder<TShardingDbContext>(_shardingCoreConfigBuilder); return new ShardingCoreConfigEndBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
} }
public ShardingReadWriteSeparationBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
{
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
return this;
}
} }
} }

View File

@ -35,5 +35,10 @@ namespace ShardingCore.DIExtensions
} }
return new ShardingReadWriteSeparationBuilder<TShardingDbContext>(_shardingCoreConfigBuilder); return new ShardingReadWriteSeparationBuilder<TShardingDbContext>(_shardingCoreConfigBuilder);
} }
public ShardingTableBuilder<TShardingDbContext> ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
{
_shardingCoreConfigBuilder.ShardingConfigOption.ReplaceShardingComparer(newShardingComparerFactory);
return this;
}
} }
} }

View File

@ -0,0 +1,34 @@
using System;
namespace ShardingCore.Extensions
{
/*
* @Author: xjm
* @Description:
* @Date: Sunday, 31 October 2021 15:41:12
* @Email: 326308290@qq.com
*/
public static class ComparableExtension
{
public static int SafeCompareToWith(this IComparable value, IComparable other, bool asc)
{
if (asc)
return SafeCompareTo(value, other);
return SafeCompareTo(other, value);
}
public static int SafeCompareTo(IComparable value, IComparable other)
{
if (null == value && null == other) {
return 0;
}
if (null == value)
{
return -1;
}
if (null == other) {
return 1;
}
return value.CompareTo(other);
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace ShardingCore.Sharding.Abstractions
{
/*
* @Author: xjm
* @Description:
* @Date: Sunday, 31 October 2021 15:07:52
* @Email: 326308290@qq.com
*/
public interface IShardingComparer
{
int Compare(IComparable a, IComparable b,bool asc);
}
public interface IShardingComparer<TShardingDbContext> : IShardingComparer where TShardingDbContext:DbContext,IShardingDbContext
{
}
}

View File

@ -0,0 +1,21 @@
using System;
using Microsoft.EntityFrameworkCore;
using ShardingCore.Extensions;
using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.Sharding
{
/*
* @Author: xjm
* @Description:
* @Date: Sunday, 31 October 2021 15:39:46
* @Email: 326308290@qq.com
*/
public class CSharpLanguageShardingComparer<TShardingDbContext>:IShardingComparer<TShardingDbContext> where TShardingDbContext:DbContext,IShardingDbContext
{
public int Compare(IComparable a, IComparable b, bool asc)
{
return a.SafeCompareToWith(b, asc);
}
}
}

View File

@ -115,7 +115,7 @@ namespace ShardingCore.Sharding.Enumerators
int i = 0; int i = 0;
foreach (var order in _mergeContext.Orders) foreach (var order in _mergeContext.Orders)
{ {
int result = CompareHelper.CompareToWith(_orderValues[i], other.GetCompares()[i], order.IsAsc); int result = _mergeContext.GetShardingComparer().Compare(_orderValues[i], other.GetCompares()[i], order.IsAsc);
if (0 != result) if (0 != result)
{ {
return result; return result;

View File

@ -47,26 +47,28 @@ namespace ShardingCore.Sharding
public IEnumerable<TableRouteResult> TableRouteResults { get; } public IEnumerable<TableRouteResult> TableRouteResults { get; }
public DataSourceRouteResult DataSourceRouteResult { get; } public DataSourceRouteResult DataSourceRouteResult { get; }
/// <summary> /// <summary>
/// 本次查询涉及的对象 /// 本次查询涉及的对象
/// </summary> /// </summary>
public ISet<Type> QueryEntities { get; } public ISet<Type> QueryEntities { get; }
/// <summary> /// <summary>
/// 本次查询是否包含notracking /// 本次查询是否包含notracking
/// </summary> /// </summary>
public bool? IsNoTracking { get; } public bool? IsNoTracking { get; }
/// <summary> /// <summary>
/// 本次查询跨库 /// 本次查询跨库
/// </summary> /// </summary>
public bool IsCrossDataSource { get; } public bool IsCrossDataSource { get; }
/// <summary> /// <summary>
/// 本次查询跨表 /// 本次查询跨表
/// </summary> /// </summary>
public bool IsCrossTable { get; } public bool IsCrossTable { get; }
private readonly ITrackerManager _trackerManager; private readonly ITrackerManager _trackerManager;
private readonly IShardingConfigOption _shardingConfigOption; private readonly IShardingConfigOption _shardingConfigOption;
private readonly ConcurrentDictionary<DbContext, object> _parallelDbContexts; private readonly ConcurrentDictionary<DbContext, object> _parallelDbContexts;
private readonly IShardingComparer _shardingComparer;
public StreamMergeContext(IQueryable<T> source, IShardingDbContext shardingDbContext, public StreamMergeContext(IQueryable<T> source, IShardingDbContext shardingDbContext,
DataSourceRouteResult dataSourceRouteResult, DataSourceRouteResult dataSourceRouteResult,
@ -93,6 +95,8 @@ namespace ShardingCore.Sharding
_trackerManager = _trackerManager =
(ITrackerManager)ShardingContainer.GetService( (ITrackerManager)ShardingContainer.GetService(
typeof(ITrackerManager<>).GetGenericType0(shardingDbContext.GetType())); typeof(ITrackerManager<>).GetGenericType0(shardingDbContext.GetType()));
_shardingComparer = (IShardingComparer)ShardingContainer.GetService(typeof(IShardingComparer<>).GetGenericType0(_shardingDbContext.GetType()));
_shardingConfigOption = ShardingContainer.GetServices<IShardingConfigOption>() _shardingConfigOption = ShardingContainer.GetServices<IShardingConfigOption>()
.FirstOrDefault(o => o.ShardingDbContextType == shardingDbContext.GetType()); .FirstOrDefault(o => o.ShardingDbContextType == shardingDbContext.GetType());
_parallelDbContexts = new ConcurrentDictionary<DbContext, object>(); _parallelDbContexts = new ConcurrentDictionary<DbContext, object>();
@ -123,7 +127,7 @@ namespace ShardingCore.Sharding
Skip = skip; Skip = skip;
} }
/// <summary> /// <summary>
/// 创建对应的dbcontext /// 创建对应的dbcontext
/// </summary> /// </summary>
/// <param name="dataSourceName">data source name</param> /// <param name="dataSourceName">data source name</param>
/// <param name="tableRouteResult"></param> /// <param name="tableRouteResult"></param>
@ -131,7 +135,7 @@ namespace ShardingCore.Sharding
public DbContext CreateDbContext(string dataSourceName, TableRouteResult tableRouteResult) public DbContext CreateDbContext(string dataSourceName, TableRouteResult tableRouteResult)
{ {
var routeTail = _routeTailFactory.Create(tableRouteResult); var routeTail = _routeTailFactory.Create(tableRouteResult);
//如果开启了读写分离或者本次查询是跨表或者跨库的表示本次查询的dbcontext是不存储的用完后就直接dispose //如果开启了读写分离或者本次查询是跨表或者跨库的表示本次查询的dbcontext是不存储的用完后就直接dispose
var parallelQuery = IsParallelQuery(); var parallelQuery = IsParallelQuery();
var dbContext = _shardingDbContext.GetDbContext(dataSourceName, parallelQuery, routeTail); var dbContext = _shardingDbContext.GetDbContext(dataSourceName, parallelQuery, routeTail);
if (parallelQuery) if (parallelQuery)
@ -190,7 +194,7 @@ namespace ShardingCore.Sharding
return _shardingConfigOption.ParallelQueryTimeOut; return _shardingConfigOption.ParallelQueryTimeOut;
} }
/// <summary> /// <summary>
/// 是否是跨资源查询 /// 是否是跨资源查询
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private bool IsCrossQuery() private bool IsCrossQuery()
@ -198,7 +202,7 @@ namespace ShardingCore.Sharding
return IsCrossDataSource || IsCrossTable; return IsCrossDataSource || IsCrossTable;
} }
/// <summary> /// <summary>
/// 是否启用读写分离 /// 是否启用读写分离
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private bool IsUseReadWriteSeparation() private bool IsUseReadWriteSeparation()
@ -207,7 +211,7 @@ namespace ShardingCore.Sharding
} }
/// <summary> /// <summary>
/// 是否使用并行查询 /// 是否使用并行查询
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private bool IsParallelQuery() private bool IsParallelQuery()
@ -216,12 +220,12 @@ namespace ShardingCore.Sharding
} }
/// <summary> /// <summary>
/// 是否使用sharding track /// 是否使用sharding track
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool IsUseShardingTrack(Type entityType) public bool IsUseShardingTrack(Type entityType)
{ {
//没有跨dbcontext查询并且不是读写分离才可以那么是否追踪之类的由查询的dbcontext自行处理 //没有跨dbcontext查询并且不是读写分离才可以那么是否追踪之类的由查询的dbcontext自行处理
if (!IsParallelQuery()) if (!IsParallelQuery())
return false; return false;
return QueryTrack() && _trackerManager.EntityUseTrack(entityType); return QueryTrack() && _trackerManager.EntityUseTrack(entityType);
@ -242,6 +246,10 @@ namespace ShardingCore.Sharding
} }
} }
public IShardingComparer GetShardingComparer()
{
return _shardingComparer;
}
public void Dispose() public void Dispose()
{ {
foreach (var dbContext in _parallelDbContexts.Keys) foreach (var dbContext in _parallelDbContexts.Keys)

View File

@ -43,6 +43,16 @@ namespace ShardingCore
{ {
DataSourcesConfigure = dataSourcesConfigure ?? throw new ArgumentNullException(nameof(dataSourcesConfigure)); DataSourcesConfigure = dataSourcesConfigure ?? throw new ArgumentNullException(nameof(dataSourcesConfigure));
} }
public Func<IServiceProvider, IShardingComparer<TShardingDbContext>> ReplaceShardingComparerFactory { get; private set; }
/// <summary>
/// 替换默认的比较器
/// </summary>
/// <param name="newShardingComparerFactory"></param>
/// <exception cref="ArgumentNullException"></exception>
public void ReplaceShardingComparer(Func<IServiceProvider, IShardingComparer<TShardingDbContext>> newShardingComparerFactory)
{
ReplaceShardingComparerFactory=newShardingComparerFactory ?? throw new ArgumentNullException(nameof(newShardingComparerFactory));
}
///// <summary> ///// <summary>