using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WorkFlowCheck.Common.RequestContext; using WorkFlowCheck.DL.Configurations; using WorkFlowCheck.DL.Extensions; using WorkFlowCheck.DL.Interfaces; namespace WorkFlowCheck.DL { public class AppDbContext : DbContext { private readonly IRequestContext _requestContext; #if !DEBUG public AppDbContext(DbContextOptions options, IRequestContext requestContext) : base(options) { _requestContext = requestContext; } #endif #if DEBUG public AppDbContext(DbContextOptions options) : base(options) { var _requestContext = new { CurrentUserEmail = "", CurrentUsername = "", TraceId = 0 }; } #endif #region Entities DbSet public DbSet CheckListHeaders { get; set; } = null!; public DbSet CheckListTemplateHeaders { get; set; } = null!; public DbSet CheckListTemplateRows { get; set; } = null!; public DbSet CheckPoints { get; set; } = null!; public DbSet Equipments { get; set; } = null!; public DbSet Locations { get; set; } = null!; public DbSet Roles { get; set; } = null!; public DbSet Users { get; set; } = null!; public DbSet UsersCheckListTemplateHeaders { get; set; } = null!; #endregion protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new EquipmentTypeConfiguration()); modelBuilder.ApplyConfiguration(new LocationTypeConfiguration()); modelBuilder.ApplyConfiguration(new UserTypeConfiguration()); modelBuilder.RegisterSoftDeleteQueryFilters(); } public override async Task SaveChangesAsync(CancellationToken cancellationToken = default) { SaveChangesCore(); return await base.SaveChangesAsync(cancellationToken); } protected virtual void SaveChangesCore() { var utcNow = DateTime.UtcNow; var deletedEntries = ChangeTracker .Entries() .Where(e => e.Entity is ISoftDeletableEntity && e.State == EntityState.Deleted); UpdateDeletedEntries(deletedEntries); var modifiedEntries = ChangeTracker .Entries() .Where(e => e.Entity is IAuditableEntity && e.State == EntityState.Modified); UpdateModifiedEntires(modifiedEntries, utcNow); var addedEntries = ChangeTracker .Entries() .Where(e => e.Entity is IAuditableEntity && e.State == EntityState.Added); UpdateAddedEntries(addedEntries, utcNow); } private void UpdateAddedEntries(IEnumerable addedEntries, DateTime utcNow) { foreach (var entry in addedEntries) { ((IAuditableEntity)entry.Entity).CreatedAt = utcNow; ((IAuditableEntity)entry.Entity).LastModAt = utcNow; ((IAuditableEntity)entry.Entity).CreatedBy = _requestContext.CurrentUsername; ((IAuditableEntity)entry.Entity).LastModBy = _requestContext.CurrentUsername; } } private void UpdateModifiedEntires(IEnumerable modifiedEntries, DateTime utcNow) { foreach (var entry in modifiedEntries) { ((IAuditableEntity)entry.Entity).LastModAt = utcNow; ((IAuditableEntity)entry.Entity).LastModBy = _requestContext.CurrentUsername; } } private void UpdateDeletedEntries(IEnumerable deletedEntries) { foreach (var entry in deletedEntries) { ((ISoftDeletableEntity)entry.Entity).IsDeleted = true; entry.State = EntityState.Modified; } } } }