using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using TeleWave.Domain.Library; namespace TeleWave.Infrastructure.Persistence.Configurations; public class GenreConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.Property(x => x.Name).IsRequired().HasMaxLength(128); builder.Property(x => x.Slug).IsRequired().HasMaxLength(64); builder.HasIndex(x => x.Slug).IsUnique(); builder .HasMany(x => x.Aliases) .WithOne() .HasForeignKey(a => a.GenreId) .OnDelete(DeleteBehavior.Cascade); builder.Navigation(x => x.Aliases).UsePropertyAccessMode(PropertyAccessMode.Field); } } public class GenreAliasConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.Property(x => x.Value).IsRequired().HasMaxLength(128); // Псевдоним однозначно указывает на жанр: иначе сопоставление метаданных стало бы неопределённым. builder.HasIndex(x => x.Value).IsUnique(); } } public class ShowGenreConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.HasKey(x => new { x.ShowId, x.GenreId }); builder.HasIndex(x => x.GenreId); // Restrict, а не Cascade: удаление жанра из справочника не должно молча снимать его со всех шоу. // Команда удаления проверяет использование заранее и возвращает управляемый конфликт. builder .HasOne() .WithMany() .HasForeignKey(x => x.GenreId) .OnDelete(DeleteBehavior.Restrict); } }