using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using API.Entities; using API.Entities.Interfaces; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; namespace API.Data { public sealed class DataContext : IdentityDbContext, AppUserRole, IdentityUserLogin, IdentityRoleClaim, IdentityUserToken> { public DataContext(DbContextOptions options) : base(options) { ChangeTracker.Tracked += OnEntityTracked; ChangeTracker.StateChanged += OnEntityStateChanged; } public DbSet Library { get; set; } public DbSet Series { get; set; } public DbSet Chapter { get; set; } public DbSet Volume { get; set; } public DbSet AppUser { get; set; } public DbSet MangaFile { get; set; } public DbSet AppUserProgresses { get; set; } public DbSet AppUserRating { get; set; } public DbSet ServerSetting { get; set; } public DbSet AppUserPreferences { get; set; } public DbSet SeriesMetadata { get; set; } public DbSet CollectionTag { get; set; } public DbSet AppUserBookmark { get; set; } public DbSet ReadingList { get; set; } public DbSet ReadingListItem { get; set; } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity() .HasMany(ur => ur.UserRoles) .WithOne(u => u.User) .HasForeignKey(ur => ur.UserId) .IsRequired(); builder.Entity() .HasMany(ur => ur.UserRoles) .WithOne(u => u.Role) .HasForeignKey(ur => ur.RoleId) .IsRequired(); } void OnEntityTracked(object sender, EntityTrackedEventArgs e) { if (!e.FromQuery && e.Entry.State == EntityState.Added && e.Entry.Entity is IEntityDate entity) { entity.Created = DateTime.Now; entity.LastModified = DateTime.Now; } } void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e) { if (e.NewState == EntityState.Modified && e.Entry.Entity is IEntityDate entity) entity.LastModified = DateTime.Now; } private void OnSaveChanges() { foreach (var saveEntity in ChangeTracker.Entries() .Where(e => e.State == EntityState.Modified) .Select(entry => entry.Entity) .OfType()) { saveEntity.OnSavingChanges(); } } #region SaveChanges overrides public override int SaveChanges() { this.OnSaveChanges(); return base.SaveChanges(); } public override int SaveChanges(bool acceptAllChangesOnSuccess) { this.OnSaveChanges(); return base.SaveChanges(acceptAllChangesOnSuccess); } public override Task SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken)) { this.OnSaveChanges(); return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken); } public override Task SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)) { this.OnSaveChanges(); return base.SaveChangesAsync(cancellationToken); } #endregion } }