优化批量操作的不分库操作,完成表达式批量操作

This commit is contained in:
xuejiaming 2021-09-23 11:47:41 +08:00
parent 8e315ddcd2
commit 97d2a76655
7 changed files with 64 additions and 49 deletions

View File

@ -537,7 +537,7 @@ AbstractSimpleShardingYearKeyLongVirtualTableRoute |按时间戳 |yyyy | `>,>=,<
注:`contains`表示为`o=>ids.contains(o.shardingkey)`
注:使用默认的按时间分表的路由规则会让你重写一个GetBeginTime的方法这个方法必须使用静态值如:new DateTime(2021,1,1)不可以用动态值比如DateTime.Now因为每次重新启动都会调用该方法动态情况下会导致每次都不一致
#高级
# 高级
## 批量操作

View File

@ -1,7 +1,8 @@
:start
::定义版本
set EFCORE3=3.2.0.20
set EFCORE5=5.2.0.20
set EFCORE2=2.3.0.00-pre1
set EFCORE3=3.3.0.00-pre1
set EFCORE5=5.3.0.00-pre1
::删除所有bin与obj下的文件
@echo off

View File

@ -212,16 +212,74 @@ namespace ShardingCore.Extensions
public DbContext InnerDbContext { get; }
public LinkedList<TEntity> InnerEntities { get; }
}
public static Dictionary<DbContext, IEnumerable<TEntity>> BulkShardingTableEnumerable<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext,
IEnumerable<TEntity> entities) where TShardingDbContext : DbContext, IShardingDbContext
where TEntity : class
{
if (typeof(TEntity).IsShardingDataSource())
throw new InvalidOperationException(typeof(TEntity).FullName);
return shardingDbContext.BulkShardingEnumerable(entities).First().Value;
}
/// <summary>
/// 根据条件表达式解析
/// </summary>
/// <typeparam name="TShardingDbContext"></typeparam>
/// <typeparam name="TEntity"></typeparam>
/// <param name="shardingDbContext"></param>
/// <param name="where"></param>
/// <returns></returns>
public static IEnumerable<DbContext> BulkShardingExpression<TEntity>(this IShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class
public static IDictionary<string, IEnumerable<DbContext>> BulkShardingExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class
where TShardingDbContext : DbContext, IShardingDbContext
{
return shardingDbContext.CreateExpressionDbContext(where);
var virtualDataSource = ShardingContainer.GetService<IVirtualDataSource<TShardingDbContext>>();
var routeTailFactory = ShardingContainer.GetService<IRouteTailFactory>();
var virtualTableManager = ShardingContainer.GetService<IVirtualTableManager<TShardingDbContext>>();
var dataSourceNames = virtualDataSource.GetDataSourceNames(where);
var result = new Dictionary<string, LinkedList<DbContext>>();
var entityType = typeof(TEntity);
foreach (var dataSourceName in dataSourceNames)
{
if (!result.TryGetValue(dataSourceName, out var dbContexts))
{
dbContexts = new LinkedList<DbContext>();
result.Add(dataSourceName, dbContexts);
}
if (entityType.IsShardingTable())
{
var physicTables = virtualTableManager.GetVirtualTable(entityType).RouteTo(new ShardingTableRouteConfig(predicate:@where));
if(physicTables.IsEmpty())
throw new ShardingCoreException($"{where.ShardingPrint()} cant found ant physic table");
var dbs = physicTables.Select(o => shardingDbContext.GetDbContext(dataSourceName, true, routeTailFactory.Create(o.Tail))).ToList();
foreach (var dbContext in dbs)
{
dbContexts.AddLast(dbContext);
}
}
else
{
var dbContext = shardingDbContext.GetDbContext(dataSourceName, true, routeTailFactory.Create(string.Empty));
dbContexts.AddLast(dbContext);
}
}
return result.ToDictionary(o=>o.Key,o=>(IEnumerable<DbContext>)o.Value);
}
public static IEnumerable<DbContext> BulkShardingTableExpression<TShardingDbContext, TEntity>(this TShardingDbContext shardingDbContext, Expression<Func<TEntity, bool>> where) where TEntity : class
where TShardingDbContext : DbContext, IShardingDbContext
{
if (typeof(TEntity).IsShardingDataSource())
throw new InvalidOperationException(typeof(TEntity).FullName);
return shardingDbContext.BulkShardingExpression<TShardingDbContext, TEntity>(where).First().Value;
}
}
}

View File

@ -86,11 +86,6 @@ namespace ShardingCore.Sharding
return _shardingDbContextExecutor.CreateGenericDbContext(entity);
}
public IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> where) where TEntity : class
{
return _shardingDbContextExecutor.CreateExpressionDbContext(where);
}
public override EntityEntry Add(object entity)

View File

@ -35,15 +35,6 @@ namespace ShardingCore.Sharding.Abstractions
/// <param name="entity"></param>
/// <returns></returns>
DbContext CreateGenericDbContext<T>(T entity) where T : class;
/// <summary>
/// 根据表达式创建db context
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="where"></param>
/// <returns></returns>
IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> where)
where TEntity : class;

View File

@ -47,8 +47,6 @@ namespace ShardingCore.Sharding.Abstractions
DbContext CreateDbContext(bool parallelQuery, string dataSourceName, IRouteTail routeTail);
DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class;
IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> where)
where TEntity : class;
IShardingTransaction BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.Unspecified);

View File

@ -159,34 +159,6 @@ namespace ShardingCore.Sharding
return CreateDbContext(true, dataSourceName, _routeTailFactory.Create(tail));
}
public IEnumerable<DbContext> CreateExpressionDbContext<TEntity>(Expression<Func<TEntity, bool>> @where) where TEntity : class
{
var dataSourceNames = _virtualDataSource.GetDataSourceNames(where);
if (typeof(TEntity).IsShardingTable())
{
var resultDbContexts = new LinkedList<DbContext>();
foreach (var dataSourceName in dataSourceNames)
{
var physicTables = _virtualTableManager.GetVirtualTable(typeof(TEntity)).RouteTo(new ShardingTableRouteConfig(predicate: where));
if (physicTables.IsEmpty())
throw new ShardingCoreException($"{where.ShardingPrint()} cant found ant physic table");
var dbContexts = physicTables.Select(o => CreateDbContext(true, dataSourceName, _routeTailFactory.Create(o.Tail))).ToList();
foreach (var dbContext in dbContexts)
{
resultDbContexts.AddLast(dbContext);
}
}
return resultDbContexts;
}
else
{
return dataSourceNames.Select(dataSourceName => CreateDbContext(true, dataSourceName, _routeTailFactory.Create(string.Empty)));
}
}
#endregion
#region transaction