修复efcore2的分库bug和移除泛型约束

This commit is contained in:
xuejiaming 2022-12-09 22:20:16 +08:00
parent b99476dd81
commit 822ab4e7c7
14 changed files with 58 additions and 42 deletions

View File

@ -73,7 +73,10 @@ namespace Sample.MySql.Controllers
[HttpGet] [HttpGet]
public async Task<IActionResult> Get() public async Task<IActionResult> Get()
{ {
using (var dbContextTransaction = _defaultTableDbContext.Database.BeginTransaction())
{
}
var x2 = await (from ut in _defaultTableDbContext.Set<SysTest>() var x2 = await (from ut in _defaultTableDbContext.Set<SysTest>()
join uu in _defaultTableDbContext.Set<SysUserLogByMonth>() join uu in _defaultTableDbContext.Set<SysUserLogByMonth>()

View File

@ -11,7 +11,7 @@ namespace Sample.SqlServer
public static DbContext CreateDbContextByString(string connectionString,IShardingRuntimeContext shardingRuntimeContext) public static DbContext CreateDbContextByString(string connectionString,IShardingRuntimeContext shardingRuntimeContext)
{ {
var dbContextOptionsBuilder = new DbContextOptionsBuilder<DefaultShardingDbContext>(); var dbContextOptionsBuilder = new DbContextOptionsBuilder<DefaultShardingDbContext>();
dbContextOptionsBuilder.UseSqlServer(connectionString).UseSharding<DefaultShardingDbContext>(shardingRuntimeContext); dbContextOptionsBuilder.UseSqlServer(connectionString).UseSharding(shardingRuntimeContext);
return new DefaultShardingDbContext(dbContextOptionsBuilder.Options); return new DefaultShardingDbContext(dbContextOptionsBuilder.Options);
} }
} }

View File

@ -23,16 +23,32 @@ namespace ShardingCore.EFCores
*/ */
public class ShardingRelationalTransaction : RelationalTransaction public class ShardingRelationalTransaction : RelationalTransaction
{ {
private readonly IShardingDbContext _shardingDbContext; private IShardingDbContext _shardingDbContext;
private readonly IShardingDbContextExecutor _shardingDbContextExecutor; private IShardingDbContextExecutor _shardingDbContextExecutor;
public ShardingRelationalTransaction(IShardingDbContext shardingDbContext, IRelationalConnection connection, DbTransaction transaction,IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned) : base(connection, transaction, logger, transactionOwned) private bool _inited = false;
public ShardingRelationalTransaction(IRelationalConnection connection, DbTransaction transaction,IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, bool transactionOwned) : base(connection, transaction, logger, transactionOwned)
{ {
}
private void CheckInit()
{
if (_inited)
{
throw new ShardingCoreInvalidOperationException($"cant repat init {nameof(ShardingRelationalTransaction)}");
}
}
public void SetShardingDbContext(IShardingDbContext shardingDbContext)
{
CheckInit();
_shardingDbContext = _shardingDbContext =
shardingDbContext??throw new ShardingCoreInvalidOperationException($"should implement {nameof(IShardingDbContext)}"); shardingDbContext??throw new ShardingCoreInvalidOperationException($"should implement {nameof(IShardingDbContext)}");
_shardingDbContextExecutor = shardingDbContext.GetShardingExecutor() ?? _shardingDbContextExecutor = shardingDbContext.GetShardingExecutor() ??
throw new ShardingCoreInvalidOperationException( throw new ShardingCoreInvalidOperationException(
$"{shardingDbContext.GetType()} cant get {nameof(IShardingDbContextExecutor)} from {nameof(shardingDbContext.GetShardingExecutor)}"); $"{shardingDbContext.GetType()} cant get {nameof(IShardingDbContextExecutor)} from {nameof(shardingDbContext.GetShardingExecutor)}");
_inited = true;
} }
//protected override void ClearTransaction() //protected override void ClearTransaction()

View File

@ -21,7 +21,7 @@ namespace ShardingCore.EFCores
*/ */
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionFactory: RelationalTransactionFactory
{ {
private readonly RelationalTransactionFactoryDependencies _dependencies; private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies) public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)
@ -32,18 +32,9 @@ namespace ShardingCore.EFCores
, IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger, , IDiagnosticsLogger<DbLoggerCategory.Database.Transaction> logger,
bool transactionOwned) bool transactionOwned)
{ {
var shardingDbContext = GetDbContext(connection) as IShardingDbContext; return new ShardingRelationalTransaction(connection, transaction, logger,
return new ShardingRelationalTransaction(shardingDbContext, connection, transaction, logger,
transactionOwned); transactionOwned);
} }
private DbContext GetDbContext(IRelationalConnection connection)
{
var namedConnectionStringResolver = ((RelationalConnectionDependencies)connection.GetPropertyValue("Dependencies")).ConnectionStringResolver;
var serviceProvider = (IServiceProvider)namedConnectionStringResolver.GetPropertyValue("ApplicationServiceProvider");
var dbContext = (DbContext)serviceProvider.GetService(typeof(TShardingDbContext));
return dbContext;
}
} }
} }
#endif #endif

View File

@ -7,6 +7,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore.Exceptions; using ShardingCore.Exceptions;
using ShardingCore.Extensions; using ShardingCore.Extensions;
@ -24,27 +25,22 @@ namespace ShardingCore.EFCores
/// <summary> /// <summary>
/// manage transaction /// manage transaction
/// </summary> /// </summary>
public class ShardingRelationalTransactionManager<TShardingDbContext> : IRelationalTransactionManager where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionManager : IRelationalTransactionManager
{ {
private readonly IRelationalConnection _relationalConnection; private readonly IRelationalConnection _relationalConnection;
private readonly ICurrentDbContext _currentDbContext;
private readonly IShardingDbContext _shardingDbContext; private readonly IShardingDbContext _shardingDbContext;
private readonly IShardingDbContextExecutor _shardingDbContextExecutor; private readonly IShardingDbContextExecutor _shardingDbContextExecutor;
public ShardingRelationalTransactionManager(IRelationalConnection relationalConnection) public ShardingRelationalTransactionManager(IRelationalConnection relationalConnection,ICurrentDbContext currentDbContext)
{ {
_relationalConnection = relationalConnection; _relationalConnection = relationalConnection;
_shardingDbContext = GetDbContext(relationalConnection) as IShardingDbContext??throw new ShardingCoreInvalidOperationException($"should implement {nameof(IShardingDbContext)}"); _currentDbContext = currentDbContext;
_shardingDbContext = currentDbContext.Context as IShardingDbContext??throw new ShardingCoreInvalidOperationException($"should implement {nameof(IShardingDbContext)}");
_shardingDbContextExecutor = _shardingDbContext.GetShardingExecutor(); _shardingDbContextExecutor = _shardingDbContext.GetShardingExecutor();
} }
private DbContext GetDbContext(IRelationalConnection connection)
{
var namedConnectionStringResolver = ((RelationalConnectionDependencies)connection.GetPropertyValue("Dependencies")).ConnectionStringResolver;
var serviceProvider = (IServiceProvider)namedConnectionStringResolver.GetPropertyValue("ApplicationServiceProvider");
var dbContext = (DbContext)serviceProvider.GetService(typeof(TShardingDbContext));
return dbContext;
}
public void ResetState() public void ResetState()
{ {
@ -77,6 +73,11 @@ namespace ShardingCore.EFCores
public IDbContextTransaction BeginTransaction(IsolationLevel isolationLevel) public IDbContextTransaction BeginTransaction(IsolationLevel isolationLevel)
{ {
var dbContextTransaction = _relationalConnection.BeginTransaction(isolationLevel); var dbContextTransaction = _relationalConnection.BeginTransaction(isolationLevel);
if (dbContextTransaction is ShardingRelationalTransaction shardingRelationalTransaction)
{
shardingRelationalTransaction.SetShardingDbContext(_shardingDbContext);
}
_shardingDbContextExecutor.NotifyShardingTransaction(); _shardingDbContextExecutor.NotifyShardingTransaction();
return dbContextTransaction; return dbContextTransaction;
} }
@ -85,6 +86,11 @@ namespace ShardingCore.EFCores
CancellationToken cancellationToken = new CancellationToken()) CancellationToken cancellationToken = new CancellationToken())
{ {
var dbContextTransaction = await _relationalConnection.BeginTransactionAsync(isolationLevel, cancellationToken); var dbContextTransaction = await _relationalConnection.BeginTransactionAsync(isolationLevel, cancellationToken);
if (dbContextTransaction is ShardingRelationalTransaction shardingRelationalTransaction)
{
shardingRelationalTransaction.SetShardingDbContext(_shardingDbContext);
}
_shardingDbContextExecutor.NotifyShardingTransaction(); _shardingDbContextExecutor.NotifyShardingTransaction();
return dbContextTransaction; return dbContextTransaction;
} }

View File

@ -20,7 +20,7 @@ namespace ShardingCore.EFCores
* @Email: 326308290@qq.com * @Email: 326308290@qq.com
*/ */
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionFactory: RelationalTransactionFactory
{ {
private readonly RelationalTransactionFactoryDependencies _dependencies; private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies) public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)

View File

@ -24,7 +24,7 @@ namespace ShardingCore.EFCores
/// <summary> /// <summary>
/// manage transaction /// manage transaction
/// </summary> /// </summary>
public class ShardingRelationalTransactionManager<TShardingDbContext> : IRelationalTransactionManager where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionManager: IRelationalTransactionManager
{ {
private readonly IRelationalConnection _relationalConnection; private readonly IRelationalConnection _relationalConnection;
private readonly IShardingDbContext _shardingDbContext; private readonly IShardingDbContext _shardingDbContext;

View File

@ -21,7 +21,7 @@ namespace ShardingCore.EFCores
*/ */
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionFactory : RelationalTransactionFactory
{ {
private readonly RelationalTransactionFactoryDependencies _dependencies; private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies) public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)

View File

@ -24,7 +24,7 @@ namespace ShardingCore.EFCores
/// <summary> /// <summary>
/// manage transaction /// manage transaction
/// </summary> /// </summary>
public class ShardingRelationalTransactionManager<TShardingDbContext> : IRelationalTransactionManager where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionManager : IRelationalTransactionManager
{ {
private readonly IRelationalConnection _relationalConnection; private readonly IRelationalConnection _relationalConnection;
private readonly IShardingDbContext _shardingDbContext; private readonly IShardingDbContext _shardingDbContext;

View File

@ -21,7 +21,7 @@ namespace ShardingCore.EFCores
*/ */
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionFactory : RelationalTransactionFactory
{ {
private readonly RelationalTransactionFactoryDependencies _dependencies; private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies) public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)

View File

@ -8,6 +8,7 @@ using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore.Storage;
using ShardingCore.Exceptions; using ShardingCore.Exceptions;
using ShardingCore.Extensions; using ShardingCore.Extensions;
@ -25,7 +26,7 @@ namespace ShardingCore.EFCores
/// <summary> /// <summary>
/// manage transaction /// manage transaction
/// </summary> /// </summary>
public class ShardingRelationalTransactionManager<TShardingDbContext> : IRelationalTransactionManager where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionManager : IRelationalTransactionManager
{ {
private readonly IRelationalConnection _relationalConnection; private readonly IRelationalConnection _relationalConnection;
private readonly IShardingDbContext _shardingDbContext; private readonly IShardingDbContext _shardingDbContext;

View File

@ -21,7 +21,7 @@ namespace ShardingCore.EFCores
*/ */
public class ShardingRelationalTransactionFactory<TShardingDbContext> : RelationalTransactionFactory where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionFactory : RelationalTransactionFactory
{ {
private readonly RelationalTransactionFactoryDependencies _dependencies; private readonly RelationalTransactionFactoryDependencies _dependencies;
public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies) public ShardingRelationalTransactionFactory(RelationalTransactionFactoryDependencies dependencies) : base(dependencies)

View File

@ -24,7 +24,7 @@ namespace ShardingCore.EFCores
/// <summary> /// <summary>
/// manage transaction /// manage transaction
/// </summary> /// </summary>
public class ShardingRelationalTransactionManager<TShardingDbContext> : IRelationalTransactionManager where TShardingDbContext : DbContext, IShardingDbContext public class ShardingRelationalTransactionManager : IRelationalTransactionManager
{ {
private readonly IRelationalConnection _relationalConnection; private readonly IRelationalConnection _relationalConnection;
private readonly IShardingDbContext _shardingDbContext; private readonly IShardingDbContext _shardingDbContext;

View File

@ -126,7 +126,7 @@ namespace ShardingCore
var contextOptionsBuilder = virtualDataSource.ConfigurationParams var contextOptionsBuilder = virtualDataSource.ConfigurationParams
.UseDbContextOptionsBuilder(connectionString, dbContextOptionsBuilder) .UseDbContextOptionsBuilder(connectionString, dbContextOptionsBuilder)
.UseShardingMigrator() .UseShardingMigrator()
.UseSharding<TShardingDbContext>(shardingRuntimeContext); .UseSharding(shardingRuntimeContext);
virtualDataSource.ConfigurationParams.UseShellDbContextOptionBuilder(contextOptionsBuilder); virtualDataSource.ConfigurationParams.UseShellDbContextOptionBuilder(contextOptionsBuilder);
return dbContextOptionsBuilder; return dbContextOptionsBuilder;
@ -210,18 +210,17 @@ namespace ShardingCore
return services; return services;
} }
public static DbContextOptionsBuilder UseSharding<TShardingDbContext>( public static DbContextOptionsBuilder UseSharding(
this DbContextOptionsBuilder optionsBuilder, IShardingRuntimeContext shardingRuntimeContext) this DbContextOptionsBuilder optionsBuilder, IShardingRuntimeContext shardingRuntimeContext)
where TShardingDbContext : DbContext, IShardingDbContext
{ {
return optionsBuilder.UseShardingWrapMark().UseShardingOptions(shardingRuntimeContext) return optionsBuilder.UseShardingWrapMark().UseShardingOptions(shardingRuntimeContext)
.ReplaceService<IDbSetSource, ShardingDbSetSource>() .ReplaceService<IDbSetSource, ShardingDbSetSource>()
.ReplaceService<IQueryCompiler, ShardingQueryCompiler>() .ReplaceService<IQueryCompiler, ShardingQueryCompiler>()
.ReplaceService<IChangeTrackerFactory, ShardingChangeTrackerFactory>() .ReplaceService<IChangeTrackerFactory, ShardingChangeTrackerFactory>()
.ReplaceService<IDbContextTransactionManager, .ReplaceService<IDbContextTransactionManager,
ShardingRelationalTransactionManager<TShardingDbContext>>() ShardingRelationalTransactionManager>()
.ReplaceService<IRelationalTransactionFactory, .ReplaceService<IRelationalTransactionFactory,
ShardingRelationalTransactionFactory<TShardingDbContext>>(); ShardingRelationalTransactionFactory>();
} }
public static DbContextOptionsBuilder UseShardingMigrator( public static DbContextOptionsBuilder UseShardingMigrator(