Files
YouTube-Manager/Manager.Data/Contexts/LibraryDbContext.cs
2025-09-02 16:01:07 +02:00

130 lines
4.1 KiB
C#

using Manager.Data.Entities;
using Manager.Data.Entities.LibraryContext;
using Manager.Data.Entities.LibraryContext.Join;
using Microsoft.EntityFrameworkCore;
namespace Manager.Data.Contexts;
public sealed class LibraryDbContext : DbContext
{
public LibraryDbContext(DbContextOptions<LibraryDbContext> options) : base(options)
{
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
ChangeTracker.LazyLoadingEnabled = false;
}
public DbSet<CaptionEntity> Captions { get; set; }
public DbSet<ChannelEntity> Channels { get; set; }
public DbSet<ClientAccountEntity> Accounts { get; set; }
public DbSet<HttpCookieEntity> HttpCookies { get; set; }
public DbSet<MediaEntity> Media { get; set; }
public DbSet<MediaFormatEntity> MediaFormats { get; set; }
public DbSet<PlaylistEntity> Playlists { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CaptionEntity>(ce =>
{
ce.ToTable("captions");
ce.HasKey(x => new { x.MediaId, x.LanguageCode });
});
modelBuilder.Entity<ChannelEntity>(channel =>
{
channel.ToTable("channels");
channel.HasKey(x => x.Id);
channel.HasMany(x => x.Media)
.WithOne()
.HasForeignKey(x => x.ChannelId);
channel.HasMany(x => x.Playlists)
.WithOne()
.HasForeignKey(x => x.ChannelId);
channel.HasOne(x => x.ClientAccount)
.WithOne()
.HasForeignKey<ClientAccountEntity>(e => e.Id);
});
modelBuilder.Entity<ClientAccountEntity>(cae =>
{
cae.ToTable("client_accounts");
cae.HasKey(x => x.Id);
cae.HasMany(x => x.HttpCookies)
.WithOne()
.HasForeignKey(x => x.ClientId);
});
modelBuilder.Entity<HttpCookieEntity>(httpce =>
{
httpce.ToTable("http_cookies");
httpce.HasKey(x => x.Name);
});
modelBuilder.Entity<MediaEntity>(me =>
{
me.ToTable("media");
me.HasKey(x => x.Id);
me.HasMany(x => x.Formats)
.WithOne()
.HasForeignKey(mf => mf.MediaId);
me.HasMany(x => x.Captions)
.WithOne()
.HasForeignKey(ce => ce.MediaId);
});
modelBuilder.Entity<MediaFormatEntity>(mfe =>
{
mfe.ToTable("media_formats");
mfe.HasKey(x => new { x.MediaId, x.Itag });
});
modelBuilder.Entity<PlaylistEntity>(ple =>
{
ple.ToTable("playlists");
ple.HasKey(x => x.Id);
});
/* Join tables */
modelBuilder.Entity<PlaylistMedia>(pmj =>
{
pmj.ToTable("join_playlist_media");
pmj.HasKey(x => new { x.PlaylistId, x.MediaId });
pmj.HasOne<PlaylistEntity>()
.WithMany(pe => pe.PlaylistMedias)
.HasForeignKey(fk => fk.PlaylistId);
pmj.HasOne<MediaEntity>()
.WithMany(me => me.PlaylistMedias)
.HasForeignKey(fk => fk.MediaId);
});
base.OnModelCreating(modelBuilder);
}
public override int SaveChanges()
{
UpdateEntryDates();
return base.SaveChanges();
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new())
{
UpdateEntryDates();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
private void UpdateEntryDates()
{
var entries = ChangeTracker.Entries().Where(x => x is { Entity: DateTimeBase, State: EntityState.Added or EntityState.Modified });
foreach (var entity in entries)
{
((DateTimeBase)entity.Entity).LastModifiedUtc = DateTime.UtcNow;
if (entity.State == EntityState.Added)
{
((DateTimeBase)entity.Entity).CreatedAtUtc = DateTime.UtcNow;
}
}
}
}