修复queryable内嵌method call expression的时候dbcontext没有被替换,发布x.6.0.32
This commit is contained in:
parent
265bfd535e
commit
38b53e883a
|
@ -1,9 +1,9 @@
|
|||
:start
|
||||
::定义版本
|
||||
set EFCORE2=2.6.0.31
|
||||
set EFCORE3=3.6.0.31
|
||||
set EFCORE5=5.6.0.31
|
||||
set EFCORE6=6.6.0.31
|
||||
set EFCORE2=2.6.0.32
|
||||
set EFCORE3=3.6.0.32
|
||||
set EFCORE5=5.6.0.32
|
||||
set EFCORE6=6.6.0.32
|
||||
|
||||
::删除所有bin与obj下的文件
|
||||
@echo off
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
using System.Data;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using ShardingCore.Core.EntityMetadatas;
|
||||
using ShardingCore.Core.VirtualRoutes;
|
||||
using ShardingCore.Core.VirtualRoutes.DataSourceRoutes.RouteRuleEngine;
|
||||
using ShardingCore.VirtualRoutes.Days;
|
||||
|
||||
namespace Sample.AutoCreateIfPresent;
|
||||
|
||||
public class Save7DayRoute:AbstractSimpleShardingDayKeyDateTimeVirtualTableRoute<OrderByHour>
|
||||
{
|
||||
public override void Configure(EntityMetadataTableBuilder<OrderByHour> builder)
|
||||
{
|
||||
builder.ShardingProperty(o => o.CreateTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动定时任务
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override bool AutoCreateTableByTime()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下次启动的时候只保留7天的
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override DateTime GetBeginTime()
|
||||
{
|
||||
return DateTime.Now.AddDays(-7);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 路由查询后置处理器
|
||||
/// must手动指定的情况下无效不会经过这个方法
|
||||
/// </summary>
|
||||
/// <param name="dataSourceRouteResult"></param>
|
||||
/// <param name="shardingRouteUnits"></param>
|
||||
/// <returns></returns>
|
||||
protected override List<TableRouteUnit> AfterShardingRouteUnitFilter(DataSourceRouteResult dataSourceRouteResult, List<TableRouteUnit> shardingRouteUnits)
|
||||
{
|
||||
var minTail = ShardingKeyToTail(DateTime.Now.AddDays(-7));
|
||||
return shardingRouteUnits.Where(o => String.Compare(o.Tail, minTail, StringComparison.Ordinal)>=0).ToList();
|
||||
// if (shardingRouteUnits.Count > 7)
|
||||
// {
|
||||
// return shardingRouteUnits.OrderByDescending(o => o.Tail).Take(7).ToList();
|
||||
// }
|
||||
//
|
||||
// return shardingRouteUnits;
|
||||
}
|
||||
|
||||
public override async Task ExecuteAsync()
|
||||
{
|
||||
await base.ExecuteAsync();
|
||||
using (var scope = RouteShardingProvider.ApplicationServiceProvider.CreateScope())
|
||||
{
|
||||
using (var defaultDbContext = scope.ServiceProvider.GetService<DefaultDbContext>())
|
||||
{
|
||||
var dbConnection = defaultDbContext.Database.GetDbConnection();
|
||||
if (dbConnection.State != ConnectionState.Open)
|
||||
{
|
||||
await dbConnection.OpenAsync();
|
||||
}
|
||||
var entityMetadataManager = RouteShardingProvider.GetRequiredService<IEntityMetadataManager>();
|
||||
|
||||
var entityMetadata = entityMetadataManager.TryGet(typeof(OrderByHour));
|
||||
var deleteTail = ShardingKeyToTail(DateTime.Now.AddHours(1).AddDays(-7));
|
||||
using (var dbCommand = dbConnection.CreateCommand())
|
||||
{
|
||||
dbCommand.CommandText =
|
||||
$"delete from {entityMetadata.LogicTableName}{entityMetadata.TableSeparator}{deleteTail};";
|
||||
await dbCommand.ExecuteNonQueryAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,11 @@ using ShardingCore.TableCreator;
|
|||
|
||||
namespace Sample.MySql.Controllers
|
||||
{
|
||||
public class ssss
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public int C { get; set; }
|
||||
}
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
|
@ -30,6 +35,11 @@ namespace Sample.MySql.Controllers
|
|||
_otherDbContext = otherDbContext;
|
||||
}
|
||||
|
||||
public IQueryable<SysUserMod> GetAll()
|
||||
{
|
||||
|
||||
return _defaultTableDbContext.Set<SysUserMod>();
|
||||
}
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
|
@ -48,6 +58,9 @@ namespace Sample.MySql.Controllers
|
|||
// using (var tran = _defaultTableDbContext.Database.BeginTransaction())
|
||||
// {
|
||||
var sysUserMods = _defaultTableDbContext.Set<SysUserMod>().OrderBy(o=>o.Id).ThenBy(o=>o.Name);
|
||||
|
||||
var sysUserMods1 = _defaultTableDbContext.Set<SysUserMod>()
|
||||
.Select(o => new ssss(){ Id = o.Id, C = GetAll().Count(x => x.Id == o.Id) }).ToList();
|
||||
var resultX = await _defaultTableDbContext.Set<SysUserMod>()
|
||||
.Where(o => o.Id == "2" || o.Id == "3").FirstOrDefaultAsync();
|
||||
var resultY = await _defaultTableDbContext.Set<SysUserMod>().FirstOrDefaultAsync(o => o.Id == "2" || o.Id == "3");
|
||||
|
|
|
@ -71,6 +71,12 @@ namespace Sample.SqlServer
|
|||
new ReadNode("X","Data Source=localhost;Initial Catalog=ShardingCoreDBXA123;Integrated Security=True;"),
|
||||
}}
|
||||
},ReadStrategyEnum.Loop);
|
||||
}).AddServiceConfigure(s =>
|
||||
{
|
||||
s.AddSingleton<ILoggerFactory>(sp => LoggerFactory.Create(builder =>
|
||||
{
|
||||
builder.AddConsole();
|
||||
}));
|
||||
}).AddShardingCore();
|
||||
//services.AddShardingDbContext<DefaultShardingDbContext1>(
|
||||
// (conn, o) =>
|
||||
|
|
|
@ -255,5 +255,12 @@ namespace ShardingCore.Extensions
|
|||
type = type.BaseType;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsMethodReturnTypeQueryableType(this Type type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
return typeof(IQueryable).IsAssignableFrom(type);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -125,6 +125,12 @@ namespace ShardingCore.Extensions
|
|||
var newExpression = replaceQueryableVisitor.Visit(source.Expression);
|
||||
return replaceQueryableVisitor.Source.Provider.CreateQuery(newExpression);
|
||||
}
|
||||
internal static IQueryable<TSource> ReplaceDbContextQueryableWithType<TSource>(this IQueryable<TSource> source, DbContext dbContext)
|
||||
{
|
||||
DbContextReplaceQueryableVisitor replaceQueryableVisitor = new DbContextReplaceQueryableVisitor(dbContext);
|
||||
var newExpression = replaceQueryableVisitor.Visit(source.Expression);
|
||||
return (IQueryable<TSource>)replaceQueryableVisitor.Source.Provider.CreateQuery(newExpression);
|
||||
}
|
||||
internal static Expression ReplaceDbContextExpression(this Expression queryExpression, DbContext dbContext)
|
||||
{
|
||||
DbContextReplaceQueryableVisitor replaceQueryableVisitor = new DbContextReplaceQueryableVisitor(dbContext);
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
{
|
||||
return ReplaceMemberExpression(queryable);
|
||||
}
|
||||
|
||||
if (value is DbContext dbContext)
|
||||
{
|
||||
return ReplaceMemberExpression(dbContext);
|
||||
|
@ -85,14 +86,50 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
Expression.Property(ConstantExpression.Constant(tempVariable), nameof(TempVariable<object>.Queryable));
|
||||
return queryableMemberReplaceExpression;
|
||||
}
|
||||
|
||||
private MemberExpression ReplaceMemberExpression(DbContext dbContext)
|
||||
{
|
||||
var tempVariableGenericType = typeof(TempDbVariable<>).GetGenericType0(dbContext.GetType());
|
||||
var tempVariable = Activator.CreateInstance(tempVariableGenericType, _dbContext);
|
||||
MemberExpression dbContextMemberReplaceExpression =
|
||||
Expression.Property(ConstantExpression.Constant(tempVariable), nameof(TempDbVariable<object>.DbContext));
|
||||
Expression.Property(ConstantExpression.Constant(tempVariable),
|
||||
nameof(TempDbVariable<object>.DbContext));
|
||||
return dbContextMemberReplaceExpression;
|
||||
}
|
||||
protected override Expression VisitMethodCall(MethodCallExpression node)
|
||||
{
|
||||
if (node.Method.ReturnType.IsMethodReturnTypeQueryableType()&&node.Method.ReturnType.IsGenericType)
|
||||
{
|
||||
#if EFCORE2 || EFCORE3
|
||||
var notRoot = node.Arguments.All(o => !(o is ConstantExpression constantExpression&&constantExpression.Value is IQueryable));
|
||||
#endif
|
||||
#if !EFCORE2 && !EFCORE3
|
||||
var notRoot = node.Arguments.All(o => !(o is QueryRootExpression));
|
||||
#endif
|
||||
if (notRoot)
|
||||
{
|
||||
var entityType = node.Method.ReturnType.GenericTypeArguments[0];
|
||||
|
||||
var whereCallExpression = ReplaceMethodCallExpression(node, entityType);
|
||||
return whereCallExpression;
|
||||
}
|
||||
}
|
||||
|
||||
return base.VisitMethodCall(node);
|
||||
}
|
||||
|
||||
private MethodCallExpression ReplaceMethodCallExpression(MethodCallExpression methodCallExpression,
|
||||
Type entityType)
|
||||
{
|
||||
MethodCallExpression whereCallExpression = Expression.Call(
|
||||
typeof(IShardingQueryableExtension),
|
||||
nameof(IShardingQueryableExtension.ReplaceDbContextQueryableWithType),
|
||||
new Type[] { entityType },
|
||||
methodCallExpression, Expression.Constant(_dbContext)
|
||||
);
|
||||
return whereCallExpression;
|
||||
}
|
||||
|
||||
|
||||
internal sealed class TempVariable<T1>
|
||||
{
|
||||
|
@ -103,6 +140,7 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
Queryable = queryable;
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class TempDbVariable<T1>
|
||||
{
|
||||
public T1 DbContext { get; }
|
||||
|
@ -112,7 +150,6 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
DbContext = dbContext;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if EFCORE2 || EFCORE3
|
||||
|
@ -170,9 +207,11 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
if (node is QueryRootExpression queryRootExpression)
|
||||
{
|
||||
var dbContextDependencies =
|
||||
typeof(DbContext).GetTypePropertyValue(_dbContext, "DbContextDependencies") as IDbContextDependencies;
|
||||
typeof(DbContext).GetTypePropertyValue(_dbContext, "DbContextDependencies") as
|
||||
IDbContextDependencies;
|
||||
var targetIQ =
|
||||
(IQueryable)((IDbSetCache)_dbContext).GetOrAddSet(dbContextDependencies.SetSource, queryRootExpression.EntityType.ClrType);
|
||||
(IQueryable)((IDbSetCache)_dbContext).GetOrAddSet(dbContextDependencies.SetSource,
|
||||
queryRootExpression.EntityType.ClrType);
|
||||
|
||||
var newQueryable = targetIQ.Provider.CreateQuery(targetIQ.Expression);
|
||||
if (Source == null)
|
||||
|
@ -204,5 +243,4 @@ namespace ShardingCore.Core.Internal.Visitors
|
|||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
Loading…
Reference in New Issue