[#255]修复EF.Property(o,property)的排序功能

This commit is contained in:
xuejiaming 2023-11-08 09:26:47 +08:00
parent 4c27f65a8e
commit 8d4066433c
7 changed files with 111 additions and 20 deletions

View File

@ -1,6 +1,8 @@
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using MySqlConnector;
using Sample.MySql.DbContexts;
using Sample.MySql.Domain.Entities;
using Sample.MySql.multi;
@ -453,6 +455,34 @@ namespace Sample.MySql.Controllers
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()
// {
@ -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();
}
}
}

View File

@ -13,6 +13,8 @@ namespace Sample.MySql
{
public static void Main(string[] args)
{
var id = Guid.NewGuid().ToString("n");
Console.WriteLine(id);
CreateHostBuilder(args).Build().Run();
}

View File

@ -57,13 +57,11 @@ namespace Sample.MySql.Shardings
protected override List<TableRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
{
Console.WriteLine("AfterShardingRouteUnitFilter:"+shardingRouteUnits.Count);
if (shardingRouteUnits.Count > 10)//如果本次命中表过多
{
return shardingRouteUnits.Take(10).ToList();//自己排序截断选择最新的10张自己加orderBy
}
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);
}
}
}

View File

@ -130,6 +130,7 @@ namespace Sample.MySql
// o.UseEntityFrameworkCoreProxies = true;
o.ThrowIfQueryRouteNotMatch = false;
o.AutoUseWriteConnectionStringAfterWriteDb = true;
o.MaxQueryConnectionsLimit = 10;
o.UseExecutorDbContextConfigure(op =>
{

View File

@ -15,7 +15,7 @@ using ShardingCore.Sharding.Abstractions;
namespace ShardingCore.EFCores
{
public class ShardingStateManager:StateManager
public class ShardingStateManager : StateManager
{
private readonly IShardingDbContext _currentShardingDbContext;
@ -41,7 +41,8 @@ namespace ShardingCore.EFCores
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();
}
@ -51,7 +52,8 @@ namespace ShardingCore.EFCores
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();
}
@ -61,7 +63,8 @@ namespace ShardingCore.EFCores
//ApplyShardingConcepts();
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())
{
@ -77,22 +80,26 @@ namespace ShardingCore.EFCores
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();
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))
{
i = await _currentShardingDbContext.GetShardingExecutor().SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
i = await _currentShardingDbContext.GetShardingExecutor()
.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
await tran.CommitAsync(cancellationToken);
}
}
else
{
i = await _currentShardingDbContext.GetShardingExecutor().SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
i = await _currentShardingDbContext.GetShardingExecutor()
.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

View File

@ -59,7 +59,7 @@ namespace ShardingCore.Sharding.MergeContexts
var orders = orderByContext.PropertyOrders;
var combineQueryable = mergeQueryCompilerContext.GetQueryCombineResult().GetCombineQueryable();
//去除分页,获取前Take+Skip数量
var reWriteQueryable = combineQueryable;
if (take.HasValue || skip.HasValue)
@ -86,6 +86,7 @@ namespace ShardingCore.Sharding.MergeContexts
//group字段不可以为空
var selectGroupKeyProperties =
selectContext.SelectProperties.Where(o => !(o is SelectAggregateProperty)).ToArray();
if (selectGroupKeyProperties.IsEmpty())
{
throw new ShardingCoreInvalidOperationException(

View File

@ -86,15 +86,47 @@ namespace ShardingCore.Core.Internal.Visitors
expression = orderMemberConvertExpression;
}
}
if (expression == null)
throw new NotSupportedException("sharding order not support ");
Type orderOwnerType = null;
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())
throw new NotSupportedException("sharding order only support property expression");
properties.Reverse();
var propertyExpression = string.Join(".", properties);
_orderByContext.PropertyOrders.AddFirst(new PropertyOrder(propertyExpression, method.Name == nameof(Queryable.OrderBy) || method.Name == nameof(Queryable.ThenBy), expression.Member.DeclaringType));
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), orderOwnerType));
}
}