添加aop针对abpvnext的处理[#226]
This commit is contained in:
parent
3875def0fa
commit
96e785ac10
|
@ -44,7 +44,7 @@ public static class MyShardingExtension
|
||||||
new Dictionary<DbContext, IEnumerable<TEntity>>()
|
new Dictionary<DbContext, IEnumerable<TEntity>>()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
shardingDbContext.CreateGenericDbContext(entitiesArray[0]),
|
shardingDbContext.GetShardingExecutor().CreateGenericDbContext(entitiesArray[0]),
|
||||||
entitiesArray
|
entitiesArray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,48 +34,25 @@ namespace Samples.AbpSharding
|
||||||
if (wrapOptionsExtension != null)
|
if (wrapOptionsExtension != null)
|
||||||
{
|
{
|
||||||
_shardingDbContextExecutor = new ShardingDbContextExecutor(this);
|
_shardingDbContextExecutor = new ShardingDbContextExecutor(this);
|
||||||
|
_shardingDbContextExecutor.EntityCreateDbContextBefore += (sender, args) =>
|
||||||
|
{
|
||||||
|
CheckAndSetShardingKeyThatSupportAutoCreate(args.Entity);
|
||||||
|
};
|
||||||
|
_shardingDbContextExecutor.CreateDbContextAfter += (sender, args) =>
|
||||||
|
{
|
||||||
|
var shardingDbContextExecutor = (IShardingDbContextExecutor)sender;
|
||||||
|
var argsDbContext = args.DbContext;
|
||||||
|
var shellDbContext = shardingDbContextExecutor.GetShellDbContext();
|
||||||
|
|
||||||
|
if (argsDbContext is AbpDbContext<TDbContext> abpDbContext&&shellDbContext is AbpDbContext<TDbContext> abpShellDbContext &&
|
||||||
|
abpDbContext.LazyServiceProvider == null)
|
||||||
|
{
|
||||||
|
abpDbContext.LazyServiceProvider = abpShellDbContext.LazyServiceProvider;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 是否是真正的执行者
|
|
||||||
/// </summary>
|
|
||||||
private bool isExecutor => _shardingDbContextExecutor == null;
|
|
||||||
|
|
||||||
//public void ShardingUpgrade()
|
|
||||||
//{
|
|
||||||
// //IsExecutor = true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
public DbContext GetDbContext(string dataSourceName, CreateDbContextStrategyEnum strategy, IRouteTail routeTail)
|
|
||||||
{
|
|
||||||
var dbContext = _shardingDbContextExecutor.CreateDbContext(strategy, dataSourceName, routeTail);
|
|
||||||
if (dbContext is AbpDbContext<TDbContext> abpDbContext)
|
|
||||||
{
|
|
||||||
abpDbContext.LazyServiceProvider = this.LazyServiceProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 根据对象创建通用的dbcontext
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="TEntity"></typeparam>
|
|
||||||
/// <param name="entity"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class
|
|
||||||
{
|
|
||||||
CheckAndSetShardingKeyThatSupportAutoCreate(entity);
|
|
||||||
var dbContext = _shardingDbContextExecutor.CreateGenericDbContext(entity);
|
|
||||||
if (dbContext is AbpDbContext<TDbContext> abpDbContext && abpDbContext.LazyServiceProvider == null)
|
|
||||||
{
|
|
||||||
abpDbContext.LazyServiceProvider = this.LazyServiceProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dbContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IShardingDbContextExecutor GetShardingExecutor()
|
public IShardingDbContextExecutor GetShardingExecutor()
|
||||||
{
|
{
|
||||||
return _shardingDbContextExecutor;
|
return _shardingDbContextExecutor;
|
||||||
|
@ -118,416 +95,19 @@ namespace Samples.AbpSharding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override EntityEntry Add(object entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
base.Add(entity);
|
|
||||||
return CreateGenericDbContext(entity).Add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry<TEntity> Add<TEntity>(TEntity entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Add(entity);
|
|
||||||
return CreateGenericDbContext(entity).Add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override ValueTask<EntityEntry<TEntity>> AddAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.AddAsync(entity, cancellationToken);
|
|
||||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override ValueTask<EntityEntry> AddAsync(object entity, CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.AddAsync(entity, cancellationToken);
|
|
||||||
return CreateGenericDbContext(entity).AddAsync(entity, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AddRange(params object[] entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.AddRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.AddRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public override void AddRange(IEnumerable<object> entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.AddRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.AddRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task AddRangeAsync(params object[] entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
await base.AddRangeAsync(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
await group.Key.AddRangeAsync(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task AddRangeAsync(IEnumerable<object> entities, CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
await base.AddRangeAsync(entities, cancellationToken);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
await group.Key.AddRangeAsync(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry<TEntity> Attach<TEntity>(TEntity entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Attach(entity);
|
|
||||||
return CreateGenericDbContext(entity).Attach(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry Attach(object entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Attach(entity);
|
|
||||||
return CreateGenericDbContext(entity).Attach(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AttachRange(params object[] entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.AttachRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.AttachRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void AttachRange(IEnumerable<object> entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.AttachRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.AttachRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//public override DatabaseFacade Database => _dbContextCaches.Any()
|
|
||||||
// ? _dbContextCaches.First().Value.Database
|
|
||||||
// : GetDbContext(true, string.Empty).Database;
|
|
||||||
|
|
||||||
public override EntityEntry<TEntity> Entry<TEntity>(TEntity entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Entry(entity);
|
|
||||||
return CreateGenericDbContext(entity).Entry(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry Entry(object entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Entry(entity);
|
|
||||||
return CreateGenericDbContext(entity).Entry(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry<TEntity> Update<TEntity>(TEntity entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Update(entity);
|
|
||||||
return CreateGenericDbContext(entity).Update(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry Update(object entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Update(entity);
|
|
||||||
return CreateGenericDbContext(entity).Update(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UpdateRange(params object[] entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.UpdateRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.UpdateRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UpdateRange(IEnumerable<object> entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.UpdateRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.UpdateRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry<TEntity> Remove<TEntity>(TEntity entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Remove(entity);
|
|
||||||
return CreateGenericDbContext(entity).Remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override EntityEntry Remove(object entity)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.Remove(entity);
|
|
||||||
return CreateGenericDbContext(entity).Remove(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RemoveRange(params object[] entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.RemoveRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.RemoveRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RemoveRange(IEnumerable<object> entities)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
{
|
|
||||||
base.RemoveRange(entities);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var groups = entities.Select(o =>
|
|
||||||
{
|
|
||||||
var dbContext = CreateGenericDbContext(o);
|
|
||||||
return new
|
|
||||||
{
|
|
||||||
DbContext = dbContext,
|
|
||||||
Entity = o
|
|
||||||
};
|
|
||||||
}).GroupBy(g => g.DbContext);
|
|
||||||
|
|
||||||
foreach (var group in groups)
|
|
||||||
{
|
|
||||||
group.Key.RemoveRange(group.Select(o => o.Entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int SaveChanges()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (isExecutor)
|
|
||||||
return base.SaveChanges();
|
|
||||||
return this.SaveChanges(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int SaveChanges(bool acceptAllChangesOnSuccess)
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.SaveChanges(acceptAllChangesOnSuccess);
|
|
||||||
//ApplyShardingConcepts();
|
|
||||||
int i = 0;
|
|
||||||
//如果是内部开的事务就内部自己消化
|
|
||||||
if (Database.CurrentTransaction == null && _shardingDbContextExecutor.IsMultiDbContext)
|
|
||||||
{
|
|
||||||
using (var tran = Database.BeginTransaction())
|
|
||||||
{
|
|
||||||
i = _shardingDbContextExecutor.SaveChanges(acceptAllChangesOnSuccess);
|
|
||||||
tran.Commit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = _shardingDbContextExecutor.SaveChanges(acceptAllChangesOnSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return base.SaveChangesAsync(cancellationToken);
|
|
||||||
return this.SaveChangesAsync(true, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
|
|
||||||
{
|
|
||||||
if (isExecutor)
|
|
||||||
return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
|
||||||
//ApplyShardingConcepts();
|
|
||||||
int i = 0;
|
|
||||||
//如果是内部开的事务就内部自己消化
|
|
||||||
if (Database.CurrentTransaction == null && _shardingDbContextExecutor.IsMultiDbContext)
|
|
||||||
{
|
|
||||||
using (var tran = await Database.BeginTransactionAsync(cancellationToken))
|
|
||||||
{
|
|
||||||
i = await _shardingDbContextExecutor.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
|
||||||
|
|
||||||
await tran.CommitAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = await _shardingDbContextExecutor.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
|
_shardingDbContextExecutor?.Dispose();
|
||||||
if (isExecutor)
|
base.Dispose();
|
||||||
{
|
|
||||||
base.Dispose();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_shardingDbContextExecutor.Dispose();
|
|
||||||
base.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async ValueTask DisposeAsync()
|
public override async ValueTask DisposeAsync()
|
||||||
{
|
{
|
||||||
if (isExecutor)
|
if (_shardingDbContextExecutor != null)
|
||||||
{
|
|
||||||
await base.DisposeAsync();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
await _shardingDbContextExecutor.DisposeAsync();
|
await _shardingDbContextExecutor.DisposeAsync();
|
||||||
|
|
||||||
await base.DisposeAsync();
|
|
||||||
}
|
}
|
||||||
|
await base.DisposeAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -15,13 +15,11 @@ namespace ShardingCore.EFCores
|
||||||
{
|
{
|
||||||
public class ShardingStateManager:StateManager
|
public class ShardingStateManager:StateManager
|
||||||
{
|
{
|
||||||
private readonly DbContext _currentDbContext;
|
|
||||||
private readonly IShardingDbContext _currentShardingDbContext;
|
private readonly IShardingDbContext _currentShardingDbContext;
|
||||||
|
|
||||||
public ShardingStateManager(StateManagerDependencies dependencies) : base(dependencies)
|
public ShardingStateManager(StateManagerDependencies dependencies) : base(dependencies)
|
||||||
{
|
{
|
||||||
_currentDbContext=dependencies.CurrentContext.Context;
|
_currentShardingDbContext = (IShardingDbContext)Context;
|
||||||
_currentShardingDbContext = (IShardingDbContext)_currentDbContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override InternalEntityEntry GetOrCreateEntry(object entity)
|
public override InternalEntityEntry GetOrCreateEntry(object entity)
|
||||||
|
@ -69,9 +67,9 @@ namespace ShardingCore.EFCores
|
||||||
//ApplyShardingConcepts();
|
//ApplyShardingConcepts();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
//如果是内部开的事务就内部自己消化
|
//如果是内部开的事务就内部自己消化
|
||||||
if (_currentDbContext.Database.AutoTransactionsEnabled&&_currentDbContext.Database.CurrentTransaction==null&&_currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
if (Context.Database.AutoTransactionsEnabled&&Context.Database.CurrentTransaction==null&&_currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
||||||
{
|
{
|
||||||
using (var tran = _currentDbContext.Database.BeginTransaction())
|
using (var tran = Context.Database.BeginTransaction())
|
||||||
{
|
{
|
||||||
i = _currentShardingDbContext.GetShardingExecutor().SaveChanges(acceptAllChangesOnSuccess);
|
i = _currentShardingDbContext.GetShardingExecutor().SaveChanges(acceptAllChangesOnSuccess);
|
||||||
tran.Commit();
|
tran.Commit();
|
||||||
|
@ -90,9 +88,9 @@ namespace ShardingCore.EFCores
|
||||||
//ApplyShardingConcepts();
|
//ApplyShardingConcepts();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
//如果是内部开的事务就内部自己消化
|
//如果是内部开的事务就内部自己消化
|
||||||
if (_currentDbContext.Database.AutoTransactionsEnabled && _currentDbContext.Database.CurrentTransaction==null && _currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
if (Context.Database.AutoTransactionsEnabled && Context.Database.CurrentTransaction==null && _currentShardingDbContext.GetShardingExecutor().IsMultiDbContext)
|
||||||
{
|
{
|
||||||
using (var tran = await _currentDbContext.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);
|
||||||
|
|
|
@ -23,6 +23,22 @@ namespace ShardingCore.Sharding.Abstractions
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用对象创建db context的前执行
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<EntityCreateDbContextBeforeEventArgs> EntityCreateDbContextBefore;
|
||||||
|
/// <summary>
|
||||||
|
/// 使用对象创建db context的后执行
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<EntityCreateDbContextAfterEventArgs> EntityCreateDbContextAfter;
|
||||||
|
/// <summary>
|
||||||
|
/// 使用tail创建db context的前执行
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<CreateDbContextBeforeEventArgs> CreateDbContextBefore;
|
||||||
|
/// <summary>
|
||||||
|
/// 使用tail创建db context的后执行
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<CreateDbContextAfterEventArgs> CreateDbContextAfter;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// has multi db context
|
/// has multi db context
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using ShardingCore.Core.VirtualRoutes.TableRoutes.RouteTails.Abstractions;
|
||||||
|
|
||||||
|
namespace ShardingCore.Sharding.Abstractions
|
||||||
|
{
|
||||||
|
public class EntityCreateDbContextBeforeEventArgs: EventArgs
|
||||||
|
{
|
||||||
|
public object Entity { get; }
|
||||||
|
|
||||||
|
public EntityCreateDbContextBeforeEventArgs(object entity)
|
||||||
|
{
|
||||||
|
Entity = entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class CreateDbContextBeforeEventArgs: EventArgs
|
||||||
|
{
|
||||||
|
public CreateDbContextStrategyEnum Strategy { get; }
|
||||||
|
public string DataSourceName { get; }
|
||||||
|
public IRouteTail RouteTail { get; }
|
||||||
|
|
||||||
|
public CreateDbContextBeforeEventArgs(CreateDbContextStrategyEnum strategy, string dataSourceName, IRouteTail routeTail)
|
||||||
|
{
|
||||||
|
Strategy = strategy;
|
||||||
|
DataSourceName = dataSourceName;
|
||||||
|
RouteTail = routeTail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class CreateDbContextAfterEventArgs: EventArgs
|
||||||
|
{
|
||||||
|
public CreateDbContextStrategyEnum Strategy { get; }
|
||||||
|
public string DataSourceName { get; }
|
||||||
|
public IRouteTail RouteTail { get; }
|
||||||
|
public DbContext DbContext { get; }
|
||||||
|
|
||||||
|
public CreateDbContextAfterEventArgs(CreateDbContextStrategyEnum strategy, string dataSourceName, IRouteTail routeTail,DbContext dbContext)
|
||||||
|
{
|
||||||
|
Strategy = strategy;
|
||||||
|
DataSourceName = dataSourceName;
|
||||||
|
RouteTail = routeTail;
|
||||||
|
DbContext = dbContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class EntityCreateDbContextAfterEventArgs: EventArgs
|
||||||
|
{
|
||||||
|
public object Entity { get; }
|
||||||
|
public DbContext DbContext { get; }
|
||||||
|
|
||||||
|
public EntityCreateDbContextAfterEventArgs(object entity,DbContext dbContext)
|
||||||
|
{
|
||||||
|
Entity = entity;
|
||||||
|
DbContext = dbContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,6 +35,13 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
|
||||||
/// <typeparam name="TShardingDbContext"></typeparam>
|
/// <typeparam name="TShardingDbContext"></typeparam>
|
||||||
public class ShardingDbContextExecutor : IShardingDbContextExecutor
|
public class ShardingDbContextExecutor : IShardingDbContextExecutor
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public event EventHandler<EntityCreateDbContextBeforeEventArgs> EntityCreateDbContextBefore;
|
||||||
|
public event EventHandler<EntityCreateDbContextAfterEventArgs> EntityCreateDbContextAfter;
|
||||||
|
public event EventHandler<CreateDbContextBeforeEventArgs> CreateDbContextBefore;
|
||||||
|
public event EventHandler<CreateDbContextAfterEventArgs> CreateDbContextAfter;
|
||||||
|
|
||||||
private readonly ILogger<ShardingDbContextExecutor> _logger;
|
private readonly ILogger<ShardingDbContextExecutor> _logger;
|
||||||
private readonly DbContext _shardingDbContext;
|
private readonly DbContext _shardingDbContext;
|
||||||
|
|
||||||
|
@ -106,19 +113,29 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
|
||||||
public DbContext CreateDbContext(CreateDbContextStrategyEnum strategy, string dataSourceName,
|
public DbContext CreateDbContext(CreateDbContextStrategyEnum strategy, string dataSourceName,
|
||||||
IRouteTail routeTail)
|
IRouteTail routeTail)
|
||||||
{
|
{
|
||||||
|
if (CreateDbContextBefore != null)
|
||||||
|
{
|
||||||
|
CreateDbContextBefore.Invoke(this,new CreateDbContextBeforeEventArgs(strategy,dataSourceName,routeTail));
|
||||||
|
}
|
||||||
|
|
||||||
|
DbContext dbContext;
|
||||||
if (CreateDbContextStrategyEnum.ShareConnection == strategy)
|
if (CreateDbContextStrategyEnum.ShareConnection == strategy)
|
||||||
{
|
{
|
||||||
var dataSourceDbContext = GetDataSourceDbContext(dataSourceName);
|
var dataSourceDbContext = GetDataSourceDbContext(dataSourceName);
|
||||||
return dataSourceDbContext.CreateDbContext(routeTail);
|
dbContext= dataSourceDbContext.CreateDbContext(routeTail);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var parallelDbContextOptions = CreateParallelDbContextOptions(dataSourceName, strategy);
|
var parallelDbContextOptions = CreateParallelDbContextOptions(dataSourceName, strategy);
|
||||||
var dbContext =
|
dbContext =
|
||||||
_dbContextCreator.CreateDbContext(_shardingDbContext, parallelDbContextOptions, routeTail);
|
_dbContextCreator.CreateDbContext(_shardingDbContext, parallelDbContextOptions, routeTail);
|
||||||
dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
|
||||||
return dbContext;
|
|
||||||
}
|
}
|
||||||
|
if (CreateDbContextAfter != null)
|
||||||
|
{
|
||||||
|
CreateDbContextAfter.Invoke(this,new CreateDbContextAfterEventArgs(strategy,dataSourceName,routeTail,dbContext));
|
||||||
|
}
|
||||||
|
return dbContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbContextOptions CreateParallelDbContextOptions(string dataSourceName,
|
private DbContextOptions CreateParallelDbContextOptions(string dataSourceName,
|
||||||
|
@ -136,12 +153,25 @@ namespace ShardingCore.Sharding.ShardingDbContextExecutors
|
||||||
|
|
||||||
public DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class
|
public DbContext CreateGenericDbContext<TEntity>(TEntity entity) where TEntity : class
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (EntityCreateDbContextBefore != null)
|
||||||
|
{
|
||||||
|
EntityCreateDbContextBefore.Invoke(this,new EntityCreateDbContextBeforeEventArgs(entity));
|
||||||
|
}
|
||||||
|
|
||||||
var realEntityType = _trackerManager.TranslateEntityType(entity.GetType());
|
var realEntityType = _trackerManager.TranslateEntityType(entity.GetType());
|
||||||
var dataSourceName = GetDataSourceName(entity,realEntityType);
|
var dataSourceName = GetDataSourceName(entity,realEntityType);
|
||||||
var tail = GetTableTail(dataSourceName, entity,realEntityType);
|
var tail = GetTableTail(dataSourceName, entity,realEntityType);
|
||||||
|
|
||||||
return CreateDbContext(CreateDbContextStrategyEnum.ShareConnection, dataSourceName,
|
var dbContext = CreateDbContext(CreateDbContextStrategyEnum.ShareConnection, dataSourceName,
|
||||||
_routeTailFactory.Create(tail));
|
_routeTailFactory.Create(tail));
|
||||||
|
|
||||||
|
if (EntityCreateDbContextAfter != null)
|
||||||
|
{
|
||||||
|
EntityCreateDbContextAfter.Invoke(this,new EntityCreateDbContextAfterEventArgs(entity,dbContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
return dbContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IVirtualDataSource GetVirtualDataSource()
|
public IVirtualDataSource GetVirtualDataSource()
|
||||||
|
|
Loading…
Reference in New Issue