using Microsoft.EntityFrameworkCore.Storage; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Data.Common; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using CloudBuilder.Core.DatabaseAccessor.Entity; using Microsoft.Extensions.DependencyInjection; namespace CloudBuilder.Core.DatabaseAccessor { public class UnitOfWork : IUnitOfWork { private readonly List _dbContexts = new List(); private DbTransaction _transaction; private DbConnection _connection; private DbContext _dbContext; /// /// 初始化一个类型的新实例 /// public UnitOfWork([FromKeyedServices(MasterDbContext.MASTER_DB_CONTEXT)] DbContext context) { _dbContext = context; _dbContexts.Add(_dbContext); _connection = _dbContext.Database.GetDbConnection(); } /// /// 获取 事务是否已提交 /// public bool HasCommitted { get; private set; } /// /// 添加DbContext共享事务 /// public void AddDbContext(DbContext dbContext) { _dbContexts.Add(dbContext); } public DbContext GetDbContext() { return _dbContext; } /// /// 对数据库连接开启事务 /// public virtual void BeginOrUseTransaction() { if (_dbContexts.Count == 0) { return; } if (_transaction?.Connection == null) { if (_connection.State != ConnectionState.Open) { _connection.Open(); } _transaction = _connection.BeginTransaction(); } foreach (DbContext context in _dbContexts) { if (context.Database.CurrentTransaction != null && context.Database.CurrentTransaction.GetDbTransaction() == _transaction) { continue; } //if (context.IsRelationalTransaction()) //{ //共享事务仅限关系数据库 context.Database.UseTransaction(_transaction); //} //else //{ // context.Database.BeginTransaction(); //} } HasCommitted = false; } /// /// 对数据库连接开启事务 /// /// 异步取消标记 /// public virtual async Task BeginOrUseTransactionAsync(CancellationToken cancellationToken = default) { if (_dbContexts.Count == 0) { return; } if (_transaction?.Connection == null) { if (_connection.State != ConnectionState.Open) { await _connection.OpenAsync(cancellationToken); } _transaction = _connection.BeginTransaction(); } foreach (DbContext context in _dbContexts) { if (context.Database.CurrentTransaction != null && context.Database.CurrentTransaction.GetDbTransaction() == _transaction) { continue; } //if (context.IsRelationalTransaction()) //{ context.Database.UseTransaction(_transaction); //} //else //{ // await context.Database.BeginTransactionAsync(cancellationToken); //} } HasCommitted = false; } /// /// 提交当前上下文的事务更改 /// public virtual void Commit() { if (HasCommitted || _dbContexts.Count == 0 || _transaction == null) { return; } _transaction.Commit(); foreach (DbContext context in _dbContexts) { //if (context.IsRelationalTransaction()) //{ context.Database.CurrentTransaction.Dispose(); //关系型数据库共享事务 continue; //} //context.Database.CommitTransaction(); } HasCommitted = true; } /// /// 回滚所有事务 /// public virtual void Rollback() { if (_transaction?.Connection != null) { _transaction.Rollback(); } foreach (var context in _dbContexts) { //if (context.IsRelationalTransaction()) //{ CleanChanges(context); if (context.Database.CurrentTransaction != null) { //context.Database.CurrentTransaction.Rollback(); context.Database.CurrentTransaction.Dispose(); } continue; //} //context.Database.RollbackTransaction(); } HasCommitted = true; } private static void CleanChanges(DbContext context) { var entries = context.ChangeTracker.Entries().ToArray(); foreach (var entry in entries) { entry.State = EntityState.Detached; } } public void Dispose() { _transaction?.Dispose(); foreach (DbContext context in _dbContexts) { context.Dispose(); } } } }