using System; using System.Collections.Generic; using System.Data; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; namespace Luticate2.Utils.DataAccess { public class LuEfTransactionScope { protected IDictionary Contexts; private readonly IServiceProvider _serviceProvider; public LuEfTransactionScope(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; Contexts = new Dictionary(); } public TDbContext GetTransactedDbContext() where TDbContext : DbContext { if (Contexts.ContainsKey(typeof(TDbContext))) { return (TDbContext) Contexts[typeof(TDbContext)]; } return null; } public bool BeginTransaction(TDbContext dbContext, IsolationLevel? level = null) where TDbContext : DbContext { if (dbContext == null) { dbContext = GetTransactedDbContext(); if (dbContext == null) { dbContext = _serviceProvider.GetService(); } } if (!Contexts.Contains(new KeyValuePair(typeof(TDbContext), dbContext))) { Contexts.Add(typeof(TDbContext), dbContext); } if (dbContext.Database.CurrentTransaction != null) { return false; } if (level == null) { dbContext.Database.BeginTransaction(); } else { dbContext.Database.BeginTransaction(level.Value); } return true; } public void CommitTransaction() where TDbContext : DbContext { try { GetTransactedDbContext().Database.CommitTransaction(); } finally { Contexts.Remove(typeof(TDbContext)); } } public void RollbackTransaction() where TDbContext : DbContext { try { GetTransactedDbContext().Database.RollbackTransaction(); } finally { Contexts.Remove(typeof(TDbContext)); } } } }