using Microsoft.EntityFrameworkCore; namespace MangaReader.Core.Data; public class MangaContext(DbContextOptions options) : DbContext(options) { public DbSet Mangas { get; set; } public DbSet MangaCovers { get; set; } public DbSet MangaTitles { get; set; } public DbSet Sources { get; set; } public DbSet MangaSources { get; set; } public DbSet Contributors { get; set; } public DbSet MangaContributors { get; set; } public DbSet Genres { get; set; } public DbSet MangaGenres { get; set; } public DbSet MangaChapters { get; set; } public DbSet ChapterSources { get; set; } public DbSet ChapterPages { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); ConfigureManga(modelBuilder); ConfigureMangaCover(modelBuilder); ConfigureMangaTitle(modelBuilder); ConfigureSource(modelBuilder); ConfigureMangaSource(modelBuilder); ConfigureContributor(modelBuilder); ConfigureMangaContributor(modelBuilder); ConfigureGenre(modelBuilder); ConfigureMangaGenre(modelBuilder); ConfigureMangaChapter(modelBuilder); ConfigureChapterSource(modelBuilder); ConfigureChapterPage(modelBuilder); } private static void ConfigureManga(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(x => x.MangaId); modelBuilder.Entity() .HasIndex(x => x.Title) .IsUnique(); modelBuilder.Entity() .HasIndex(x => x.Slug) .IsUnique(); } private static void ConfigureMangaCover(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(x => x.MangaCoverId); modelBuilder .Entity() .HasOne(x => x.Manga) .WithMany(x => x.Covers) .HasForeignKey(x => x.MangaId) .OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity() .HasIndex(x => x.Guid) .IsUnique(); //modelBuilder // .Entity() // .HasIndex(x => new { x.MangaId, x.IsPrimary }) // .IsUnique() // .HasFilter("[IsPrimary] = 1"); // Enforce only one primary cover per manga } private static void ConfigureMangaTitle(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(mangaTitle => mangaTitle.MangaTitleId); modelBuilder.Entity() .HasIndex(mangaTitle => new { mangaTitle.MangaId, mangaTitle.Name }) .IsUnique(); modelBuilder .Entity() .HasIndex(mangaTitle => mangaTitle.Name); modelBuilder .Entity() .HasOne(x => x.Manga) .WithMany(x => x.Titles) .HasForeignKey(x => x.MangaId) .OnDelete(DeleteBehavior.Cascade); } private static void ConfigureSource(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(x => x.SourceId); modelBuilder .Entity() .HasIndex(x => x.Name) .IsUnique(true); } private static void ConfigureMangaSource(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(mangaSource => new { mangaSource.MangaId, mangaSource.SourceId }); modelBuilder.Entity() .HasIndex(x => x.Url) .IsUnique(); modelBuilder .Entity() .HasOne(x => x.Manga) .WithMany(x => x.Sources) .HasForeignKey(x => x.MangaId) .OnDelete(DeleteBehavior.Cascade); } private static void ConfigureContributor(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(x => x.ContributorId); modelBuilder .Entity() .HasIndex(x => x.Name) .IsUnique(true); } private static void ConfigureMangaContributor(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(mc => new { mc.MangaId, mc.ContributorId, mc.Role }); modelBuilder .Entity() .HasOne(x => x.Manga) .WithMany(x => x.Contributors) .HasForeignKey(x => x.MangaId) .OnDelete(DeleteBehavior.Cascade); } private static void ConfigureGenre(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(x => x.GenreId); modelBuilder .Entity() .HasIndex(x => x.Name) .IsUnique(true); } private static void ConfigureMangaGenre(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(mangaGenre => new { mangaGenre.MangaId, mangaGenre.GenreId }); modelBuilder .Entity() .HasOne(x => x.Manga) .WithMany(x => x.Genres) .HasForeignKey(x => x.MangaId) .OnDelete(DeleteBehavior.Cascade); } private static void ConfigureMangaChapter(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(x => x.MangaChapterId); modelBuilder .Entity() .HasOne(x => x.Manga) .WithMany(x => x.Chapters) .HasForeignKey(x => x.MangaId) .OnDelete(DeleteBehavior.Cascade); } private static void ConfigureChapterSource(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(chapterSource => new { chapterSource.MangaChapterId, chapterSource.SourceId }); modelBuilder .Entity() .HasOne(x => x.Chapter) .WithMany(x => x.Sources) .HasForeignKey(x => x.MangaChapterId) .OnDelete(DeleteBehavior.Cascade); } private static void ConfigureChapterPage(ModelBuilder modelBuilder) { modelBuilder .Entity() .HasKey(chapterPage => chapterPage.ChapterPageId); modelBuilder .Entity() .HasIndex(chapterPage => new { chapterPage.MangaChapterId, chapterPage.PageNumber }) .IsUnique(true); modelBuilder .Entity() .HasOne(x => x.MangaChapter) .WithMany(x => x.Pages) .HasForeignKey(x => x.MangaChapterId) .OnDelete(DeleteBehavior.Cascade); } }