using AyCode.Core.Helpers; using AyCode.Database.DataLayers; using AyCode.Database.DbContexts; using AyCode.Interfaces.Entities; using AyCode.Utils.Extensions; using Microsoft.EntityFrameworkCore; namespace AyCode.Database.Extensions; public static class AcDalExtension { public static Task SessionAsync(this IAcDalBase acDal, Func callback) where TDbContext : AcDbContextBase => TaskHelper.ToThreadPoolTask(() => acDal.Session(callback)); public static Task> SessionAsync(this IAcDalBase acDal, Func> callback) where TEntity : IEntity where TDbContext : AcDbContextBase => TaskHelper.ToThreadPoolTask(() => acDal.Session(callback)); public static TResultType Session(this IAcDalBase acDal, Func callback) where TDbContext : AcDbContextBase { //using var ctx = acDal.CreateDbContext(); using (acDal.MutextLock.UseWaitOne()) { return acDal.Context.Session(callback); } } public static IEnumerable Session(this IAcDalBase acDal, Func> callback) where TEntity : IEntity where TDbContext : AcDbContextBase { //using var ctx = acDal.CreateDbContext(); using (acDal.MutextLock.UseWaitOne()) { return acDal.Context.Session(callback); } } public static Task TransactionAsync(this IAcDalBase acDal, Func callbackTransactionBody, bool throwException = false) where TDbContext : AcDbContextBase => TaskHelper.ToThreadPoolTask(() => acDal.Transaction(callbackTransactionBody, throwException)); public static bool Transaction(this IAcDalBase acDal, Func callbackTransactionBody, bool throwException = false) where TDbContext : AcDbContextBase { //using var ctx = acDal.CreateDbContext(); using (acDal.MutextLock.UseWaitOne()) { return acDal.Context.Transaction(callbackTransactionBody, throwException); } } public static Task UpdateSafeAsync(this IAcDalBase acDal, TEntity entity, Func? callbackTransactionBody = null, bool throwException = false) where TDbContext : AcDbContextBase where TEntity : class, IEntityGuid => TaskHelper.ToThreadPoolTask(() => acDal.UpdateSafe(entity, callbackTransactionBody, throwException)); public static TEntity? UpdateSafe(this IAcDalBase acDal, TEntity entity, Func? callbackTransactionBody = null, bool throwException = false) where TDbContext : AcDbContextBase where TEntity : class, IEntityGuid { TEntity? updateEntity = null; var isSuccess = acDal.Context.Transaction(ctx => { updateEntity = ctx.Set().FirstOrDefault(x => x.Id == entity.Id); if (updateEntity == null) return false; //ctx.Entry(updateEntity).State = EntityState.Detached; ctx.Entry(updateEntity).CurrentValues.SetValues(entity); if (callbackTransactionBody == null) return ctx.Update(updateEntity).State == EntityState.Modified; return callbackTransactionBody.Invoke(ctx, updateEntity); }, throwException); return isSuccess ? updateEntity : null; } }