namespace HrynCo.DAL.EF.Core; using HrynCo.Common; using HrynCo.DAL.Abstract.Entities; using HrynCo.DAL.EF.Converters; using HrynCo.DAL.EF.Exceptions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata; public abstract class BaseDbContext : DbContext { private readonly IClock _clock; protected BaseDbContext(DbContextOptions options, IClock clock) : base(options) { _clock = clock; } public override int SaveChanges() { ApplyTimestamps(); return base.SaveChanges(); } public override async Task SaveChangesAsync(CancellationToken cancellationToken = default) { ApplyTimestamps(); return await base.SaveChangesAsync(cancellationToken); } private void ApplyTimestamps() { DateTimeOffset now = _clock.UtcNow; foreach (EntityEntry entry in ChangeTracker.Entries()) { switch (entry.State) { case EntityState.Added: entry.Entity.Created = now; break; case EntityState.Modified: entry.Entity.Updated = now; break; case EntityState.Detached: case EntityState.Unchanged: case EntityState.Deleted: break; default: throw new UnexpectedEntityStateException(entry.State); } } } protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) { configurationBuilder.Properties().HaveConversion(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (IMutableForeignKey relationship in modelBuilder.Model.GetEntityTypes() .SelectMany(e => e.GetForeignKeys())) { relationship.DeleteBehavior = DeleteBehavior.Restrict; } modelBuilder.ApplyConfigurationsFromAssembly(GetType().Assembly); base.OnModelCreating(modelBuilder); } }