[#255]修复EF.Property(o,property)的排序功能
This commit is contained in:
parent
4c27f65a8e
commit
8d4066433c
|
@ -1,6 +1,8 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage;
|
||||||
|
using MySqlConnector;
|
||||||
using Sample.MySql.DbContexts;
|
using Sample.MySql.DbContexts;
|
||||||
using Sample.MySql.Domain.Entities;
|
using Sample.MySql.Domain.Entities;
|
||||||
using Sample.MySql.multi;
|
using Sample.MySql.multi;
|
||||||
|
@ -453,6 +455,34 @@ namespace Sample.MySql.Controllers
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> Get17()
|
||||||
|
{
|
||||||
|
var sysUserMods = await _defaultTableDbContext.SysUserMod.AsNoTracking()
|
||||||
|
.Select(o => new SysUserMod()
|
||||||
|
{
|
||||||
|
Name = o.Name,
|
||||||
|
Age = o.Age
|
||||||
|
}).OrderBy(x => EF.Property<object>(x, "Name")).ToListAsync();
|
||||||
|
|
||||||
|
// var sysUserMods1 = await _defaultTableDbContext.Set<SysUserMod>().FromSqlRaw("select * from SysUserMod where id='2'").ToListAsync();
|
||||||
|
// var sysUserMods2 = await _defaultTableDbContext.Set<SysTest>().FromSqlRaw("select * from SysTest where id='2'").ToListAsync();
|
||||||
|
return Ok(sysUserMods);
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> Get18()
|
||||||
|
{
|
||||||
|
var sysUserMods = await _defaultTableDbContext.SysUserMod.AsNoTracking().GroupBy(o => o.Age)
|
||||||
|
.Select(o=>new
|
||||||
|
{
|
||||||
|
Age=o.Key
|
||||||
|
})
|
||||||
|
.CountAsync();
|
||||||
|
|
||||||
|
// var sysUserMods1 = await _defaultTableDbContext.Set<SysUserMod>().FromSqlRaw("select * from SysUserMod where id='2'").ToListAsync();
|
||||||
|
// var sysUserMods2 = await _defaultTableDbContext.Set<SysTest>().FromSqlRaw("select * from SysTest where id='2'").ToListAsync();
|
||||||
|
return Ok(sysUserMods);
|
||||||
|
}
|
||||||
|
|
||||||
// public void batachSave()
|
// public void batachSave()
|
||||||
// {
|
// {
|
||||||
|
@ -469,5 +499,25 @@ namespace Sample.MySql.Controllers
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
public void get11()
|
||||||
|
{
|
||||||
|
var mySqlConnection = new MySqlConnection("链接字符串");
|
||||||
|
var dbContextOptions1 = new DbContextOptionsBuilder<UnShardingDbContext>().UseMySql(mySqlConnection,new MySqlServerVersion(new Version()),b=>
|
||||||
|
{
|
||||||
|
b.EnableRetryOnFailure(10, TimeSpan.FromSeconds(10), null);
|
||||||
|
}).Options;
|
||||||
|
var dbContextOptions2 = new DbContextOptionsBuilder<UnShardingDbContext>().UseMySql(mySqlConnection,new MySqlServerVersion(new Version())).Options;
|
||||||
|
var unShardingDbContext1 = new UnShardingDbContext(dbContextOptions1);//映射到202301模型
|
||||||
|
var unShardingDbContext2 = new UnShardingDbContext(dbContextOptions2);//映射到202302模型
|
||||||
|
// unShardingDbContext2.Database.CreateExecutionStrategy()
|
||||||
|
var dbContextTransaction = unShardingDbContext1.Database.BeginTransaction();
|
||||||
|
unShardingDbContext2.Database.UseTransaction(dbContextTransaction.GetDbTransaction());
|
||||||
|
//unShardingDbContext1.add()
|
||||||
|
//unShardingDbContext2.add()
|
||||||
|
unShardingDbContext1.SaveChanges();
|
||||||
|
unShardingDbContext2.SaveChanges();
|
||||||
|
dbContextTransaction.Commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ namespace Sample.MySql
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
var id = Guid.NewGuid().ToString("n");
|
||||||
|
Console.WriteLine(id);
|
||||||
CreateHostBuilder(args).Build().Run();
|
CreateHostBuilder(args).Build().Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,13 +57,11 @@ namespace Sample.MySql.Shardings
|
||||||
protected override List<TableRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
|
protected override List<TableRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
|
||||||
{
|
{
|
||||||
Console.WriteLine("AfterShardingRouteUnitFilter:"+shardingRouteUnits.Count);
|
Console.WriteLine("AfterShardingRouteUnitFilter:"+shardingRouteUnits.Count);
|
||||||
|
if (shardingRouteUnits.Count > 10)//如果本次命中表过多
|
||||||
|
{
|
||||||
|
return shardingRouteUnits.Take(10).ToList();//自己排序截断选择最新的10张自己加orderBy
|
||||||
|
}
|
||||||
return base.AfterShardingRouteUnitFilter(dataSourceRouteResult, shardingRouteUnits);
|
return base.AfterShardingRouteUnitFilter(dataSourceRouteResult, shardingRouteUnits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Func<string, bool> GetRouteFilter(object shardingKey, ShardingOperatorEnum shardingOperator, string shardingPropertyName)
|
|
||||||
{
|
|
||||||
Console.WriteLine(1);
|
|
||||||
return base.GetRouteFilter(shardingKey, shardingOperator, shardingPropertyName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,7 @@ namespace Sample.MySql
|
||||||
// o.UseEntityFrameworkCoreProxies = true;
|
// o.UseEntityFrameworkCoreProxies = true;
|
||||||
o.ThrowIfQueryRouteNotMatch = false;
|
o.ThrowIfQueryRouteNotMatch = false;
|
||||||
o.AutoUseWriteConnectionStringAfterWriteDb = true;
|
o.AutoUseWriteConnectionStringAfterWriteDb = true;
|
||||||
|
o.MaxQueryConnectionsLimit = 10;
|
||||||
o.UseExecutorDbContextConfigure(op =>
|
o.UseExecutorDbContextConfigure(op =>
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ using ShardingCore.Sharding.Abstractions;
|
||||||
|
|
||||||
namespace ShardingCore.EFCores
|
namespace ShardingCore.EFCores
|
||||||
{
|
{
|
||||||
public class ShardingStateManager:StateManager
|
public class ShardingStateManager : StateManager
|
||||||
{
|
{
|
||||||
private readonly IShardingDbContext _currentShardingDbContext;
|
private readonly IShardingDbContext _currentShardingDbContext;
|
||||||
|
|
||||||
|
@ -41,7 +41,8 @@ namespace ShardingCore.EFCores
|
||||||
return stateManager.GetOrCreateEntry(entity, findEntityType);
|
return stateManager.GetOrCreateEntry(entity, findEntityType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override InternalEntityEntry StartTrackingFromQuery(IEntityType baseEntityType, object entity, in ValueBuffer valueBuffer)
|
public override InternalEntityEntry StartTrackingFromQuery(IEntityType baseEntityType, object entity,
|
||||||
|
in ValueBuffer valueBuffer)
|
||||||
{
|
{
|
||||||
throw new ShardingCoreNotImplementedException();
|
throw new ShardingCoreNotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -51,7 +52,8 @@ namespace ShardingCore.EFCores
|
||||||
throw new ShardingCoreNotImplementedException();
|
throw new ShardingCoreNotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override InternalEntityEntry TryGetEntry(object entity, IEntityType entityType, bool throwOnTypeMismatch = true)
|
public override InternalEntityEntry TryGetEntry(object entity, IEntityType entityType,
|
||||||
|
bool throwOnTypeMismatch = true)
|
||||||
{
|
{
|
||||||
throw new ShardingCoreNotImplementedException();
|
throw new ShardingCoreNotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -61,7 +63,8 @@ namespace ShardingCore.EFCores
|
||||||
//ApplyShardingConcepts();
|
//ApplyShardingConcepts();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
//如果是内部开的事务就内部自己消化
|
//如果是内部开的事务就内部自己消化
|
||||||
if (Context.Database.AutoTransactionsEnabled&&Context.Database.CurrentTransaction==null&&_currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
if (Context.Database.AutoTransactionsEnabled && Context.Database.CurrentTransaction == null &&
|
||||||
|
_currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
||||||
{
|
{
|
||||||
using (var tran = Context.Database.BeginTransaction())
|
using (var tran = Context.Database.BeginTransaction())
|
||||||
{
|
{
|
||||||
|
@ -77,22 +80,26 @@ namespace ShardingCore.EFCores
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
|
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess,
|
||||||
|
CancellationToken cancellationToken = new CancellationToken())
|
||||||
{
|
{
|
||||||
//ApplyShardingConcepts();
|
//ApplyShardingConcepts();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
//如果是内部开的事务就内部自己消化
|
//如果是内部开的事务就内部自己消化
|
||||||
if (Context.Database.AutoTransactionsEnabled && Context.Database.CurrentTransaction==null && _currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
if (Context.Database.AutoTransactionsEnabled && Context.Database.CurrentTransaction == null &&
|
||||||
|
_currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
||||||
{
|
{
|
||||||
using (var tran = await Context.Database.BeginTransactionAsync(cancellationToken))
|
using (var tran = await Context.Database.BeginTransactionAsync(cancellationToken))
|
||||||
{
|
{
|
||||||
i = await _currentShardingDbContext.GetShardingExecutor().SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
i = await _currentShardingDbContext.GetShardingExecutor()
|
||||||
|
.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||||
await tran.CommitAsync(cancellationToken);
|
await tran.CommitAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = await _currentShardingDbContext.GetShardingExecutor().SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
i = await _currentShardingDbContext.GetShardingExecutor()
|
||||||
|
.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace ShardingCore.Sharding.MergeContexts
|
||||||
var orders = orderByContext.PropertyOrders;
|
var orders = orderByContext.PropertyOrders;
|
||||||
|
|
||||||
var combineQueryable = mergeQueryCompilerContext.GetQueryCombineResult().GetCombineQueryable();
|
var combineQueryable = mergeQueryCompilerContext.GetQueryCombineResult().GetCombineQueryable();
|
||||||
|
|
||||||
//去除分页,获取前Take+Skip数量
|
//去除分页,获取前Take+Skip数量
|
||||||
var reWriteQueryable = combineQueryable;
|
var reWriteQueryable = combineQueryable;
|
||||||
if (take.HasValue || skip.HasValue)
|
if (take.HasValue || skip.HasValue)
|
||||||
|
@ -86,6 +86,7 @@ namespace ShardingCore.Sharding.MergeContexts
|
||||||
//group字段不可以为空
|
//group字段不可以为空
|
||||||
var selectGroupKeyProperties =
|
var selectGroupKeyProperties =
|
||||||
selectContext.SelectProperties.Where(o => !(o is SelectAggregateProperty)).ToArray();
|
selectContext.SelectProperties.Where(o => !(o is SelectAggregateProperty)).ToArray();
|
||||||
|
|
||||||
if (selectGroupKeyProperties.IsEmpty())
|
if (selectGroupKeyProperties.IsEmpty())
|
||||||
{
|
{
|
||||||
throw new ShardingCoreInvalidOperationException(
|
throw new ShardingCoreInvalidOperationException(
|
||||||
|
|
|
@ -86,15 +86,47 @@ namespace ShardingCore.Core.Internal.Visitors
|
||||||
expression = orderMemberConvertExpression;
|
expression = orderMemberConvertExpression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (expression == null)
|
|
||||||
throw new NotSupportedException("sharding order not support ");
|
Type orderOwnerType = null;
|
||||||
List<string> properties = new List<string>();
|
List<string> properties = new List<string>();
|
||||||
GetPropertyInfo(properties, expression);
|
if (expression != null)
|
||||||
|
{
|
||||||
|
GetPropertyInfo(properties, expression);
|
||||||
|
orderOwnerType = expression.Member.DeclaringType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(orderbody.NodeType == ExpressionType.Call && orderbody is MethodCallExpression methodCallExpression)
|
||||||
|
{
|
||||||
|
if (methodCallExpression.Method.DeclaringType == typeof(Microsoft.EntityFrameworkCore.EF))
|
||||||
|
{
|
||||||
|
if (methodCallExpression.Arguments.Count != 2)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("sharding order EF.Property(o,property) not support,arguments count != 2");
|
||||||
|
}
|
||||||
|
orderOwnerType = methodCallExpression.Arguments[0].Type;
|
||||||
|
if (methodCallExpression.Arguments[1] is ConstantExpression propertyConstantExpression)
|
||||||
|
{
|
||||||
|
properties.Add(propertyConstantExpression.Value.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("sharding order EF.Property(o,property) not support,arguments[1] is not ConstantExpression");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties.Count == 0)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("sharding order not support ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!properties.Any())
|
if (!properties.Any())
|
||||||
throw new NotSupportedException("sharding order only support property expression");
|
throw new NotSupportedException("sharding order only support property expression");
|
||||||
properties.Reverse();
|
properties.Reverse();
|
||||||
var propertyExpression = string.Join(".", properties);
|
var propertyExpression =properties.Count==1?properties[0]: string.Join(".", properties);
|
||||||
_orderByContext.PropertyOrders.AddFirst(new PropertyOrder(propertyExpression, method.Name == nameof(Queryable.OrderBy) || method.Name == nameof(Queryable.ThenBy), expression.Member.DeclaringType));
|
_orderByContext.PropertyOrders.AddFirst(new PropertyOrder(propertyExpression, method.Name == nameof(Queryable.OrderBy) || method.Name == nameof(Queryable.ThenBy), orderOwnerType));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue