From a8b658a5eaee291e45f7491c273ec5549077c833 Mon Sep 17 00:00:00 2001 From: Jason Dove <1695733+jasongdove@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:21:52 -0500 Subject: [PATCH] add "on demand" channel progress mode (#1790) * update dependencies * add channel progress mode * implement on demand channel progress * update changelog --- CHANGELOG.md | 7 + .../Channels/ChannelViewModel.cs | 1 + .../Channels/Commands/CreateChannel.cs | 1 + .../Channels/Commands/CreateChannelHandler.cs | 1 + .../Channels/Commands/UpdateChannel.cs | 1 + .../Channels/Commands/UpdateChannelHandler.cs | 1 + ErsatzTV.Application/Channels/Mapper.cs | 1 + .../ErsatzTV.Application.csproj | 6 +- .../Commands/CreateFloodPlayoutHandler.cs | 4 + .../Commands/TimeShiftOnDemandPlayout.cs | 6 + .../TimeShiftOnDemandPlayoutHandler.cs | 41 + .../UpdateExternalJsonPlayoutHandler.cs | 3 +- .../Commands/UpdateOnDemandCheckpoint.cs | 4 + .../UpdateOnDemandCheckpointHandler.cs | 62 + .../Playouts/Commands/UpdatePlayoutHandler.cs | 3 +- .../Playouts/PlayoutNameViewModel.cs | 6 +- .../Playouts/Queries/GetAllPlayoutsHandler.cs | 3 +- .../Streaming/HlsSessionWorker.cs | 17 +- .../Streaming/HlsSessionWorkerV2.cs | 17 +- .../ErsatzTV.Core.Tests.csproj | 6 +- .../Scheduling/PlayoutBuilderTests.cs | 19 + .../Scheduling/ScheduleIntegrationTests.cs | 2 + ErsatzTV.Core/Domain/Channel.cs | 1 + ErsatzTV.Core/Domain/ChannelProgressMode.cs | 7 + ErsatzTV.Core/Domain/Playout.cs | 1 + ErsatzTV.Core/ErsatzTV.Core.csproj | 10 +- .../Scheduling/IPlayoutTimeShifter.cs | 8 + ErsatzTV.Core/Scheduling/PlayoutBuilder.cs | 54 +- .../Scheduling/PlayoutTimeShifter.cs | 90 + ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj | 2 +- .../ErsatzTV.Infrastructure.MySql.csproj | 2 +- ...41648_Add_Channel_ProgressMode.Designer.cs | 5802 ++++++++++++++++ ...20240716141648_Add_Channel_ProgressMode.cs | 29 + ...Add_Playout_OnDemandCheckpoint.Designer.cs | 5805 +++++++++++++++++ ...16155846_Add_Playout_OnDemandCheckpoint.cs | 29 + .../Migrations/TvContextModelSnapshot.cs | 8 +- .../ErsatzTV.Infrastructure.Sqlite.csproj | 4 +- ...35729_Add_Channel_ProgressMode.Designer.cs | 5641 ++++++++++++++++ ...20240716135729_Add_Channel_ProgressMode.cs | 29 + ...Add_Playout_OnDemandCheckpoint.Designer.cs | 5644 ++++++++++++++++ ...16150019_Add_Playout_OnDemandCheckpoint.cs | 29 + .../Migrations/TvContextModelSnapshot.cs | 8 +- .../ErsatzTV.Infrastructure.csproj | 16 +- .../ErsatzTV.Scanner.Tests.csproj | 2 +- ErsatzTV.Scanner/ErsatzTV.Scanner.csproj | 12 +- ErsatzTV/ErsatzTV.csproj | 24 +- ErsatzTV/Pages/ChannelEditor.razor | 5 + ErsatzTV/Pages/Playouts.razor | 24 +- ErsatzTV/Services/WorkerService.cs | 3 + ErsatzTV/Startup.cs | 2 + ErsatzTV/ViewModels/ChannelEditViewModel.cs | 3 + 51 files changed, 23439 insertions(+), 67 deletions(-) create mode 100644 ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayout.cs create mode 100644 ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs create mode 100644 ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpoint.cs create mode 100644 ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpointHandler.cs create mode 100644 ErsatzTV.Core/Domain/ChannelProgressMode.cs create mode 100644 ErsatzTV.Core/Interfaces/Scheduling/IPlayoutTimeShifter.cs create mode 100644 ErsatzTV.Core/Scheduling/PlayoutTimeShifter.cs create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.Designer.cs create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.cs create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.Designer.cs create mode 100644 ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.cs create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.Designer.cs create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.cs create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.Designer.cs create mode 100644 ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index f136cf0e..5128d364 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - These libraries will now appear as ETV Other Video libraries - Items in these libraries will have tag metadata added from folders just like local Other Video libraries - Thanks @raknam for adding this feature! +- Add *experimental* support for `On Demand` channel progress + - With `On Demand` channel progress, the schedule will only advance when the channel is being streamed + - When the channel is idle, the schedule is unmodified and will be shifted forward as needed so no content is missed + - Setting a channel to `On Demand` progress will disable alternate schedules + - The `On Demand` setting will only be used for `Flood` playouts (NOT `Block` or `External JSON`) + - It is NOT recommended to use fixed start times with `On Demand` progress + - This will probably be disabled with a future update ### Fixed - Add basic cache busting to XMLTV image URLs diff --git a/ErsatzTV.Application/Channels/ChannelViewModel.cs b/ErsatzTV.Application/Channels/ChannelViewModel.cs index 8faa3f6d..0fc9b999 100644 --- a/ErsatzTV.Application/Channels/ChannelViewModel.cs +++ b/ErsatzTV.Application/Channels/ChannelViewModel.cs @@ -12,6 +12,7 @@ public record ChannelViewModel( string Logo, string PreferredAudioLanguageCode, string PreferredAudioTitle, + ChannelProgressMode ProgressMode, StreamingMode StreamingMode, int? WatermarkId, int? FallbackFillerId, diff --git a/ErsatzTV.Application/Channels/Commands/CreateChannel.cs b/ErsatzTV.Application/Channels/Commands/CreateChannel.cs index e3427b58..b0682ca2 100644 --- a/ErsatzTV.Application/Channels/Commands/CreateChannel.cs +++ b/ErsatzTV.Application/Channels/Commands/CreateChannel.cs @@ -12,6 +12,7 @@ public record CreateChannel( string Logo, string PreferredAudioLanguageCode, string PreferredAudioTitle, + ChannelProgressMode ProgressMode, StreamingMode StreamingMode, int? WatermarkId, int? FallbackFillerId, diff --git a/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs b/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs index 72f48314..0ad8c330 100644 --- a/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs +++ b/ErsatzTV.Application/Channels/Commands/CreateChannelHandler.cs @@ -73,6 +73,7 @@ public class CreateChannelHandler( Group = request.Group, Categories = request.Categories, FFmpegProfileId = ffmpegProfileId, + ProgressMode = request.ProgressMode, StreamingMode = request.StreamingMode, Artwork = artwork, PreferredAudioLanguageCode = preferredAudioLanguageCode, diff --git a/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs b/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs index 96667106..3857e693 100644 --- a/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs +++ b/ErsatzTV.Application/Channels/Commands/UpdateChannel.cs @@ -13,6 +13,7 @@ public record UpdateChannel( string Logo, string PreferredAudioLanguageCode, string PreferredAudioTitle, + ChannelProgressMode ProgressMode, StreamingMode StreamingMode, int? WatermarkId, int? FallbackFillerId, diff --git a/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs b/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs index b0ca4ec0..e7005b5e 100644 --- a/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs +++ b/ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs @@ -67,6 +67,7 @@ public class UpdateChannelHandler( }); } + c.ProgressMode = update.ProgressMode; c.StreamingMode = update.StreamingMode; c.WatermarkId = update.WatermarkId; c.FallbackFillerId = update.FallbackFillerId; diff --git a/ErsatzTV.Application/Channels/Mapper.cs b/ErsatzTV.Application/Channels/Mapper.cs index 8ec03bd6..0ac3ff3b 100644 --- a/ErsatzTV.Application/Channels/Mapper.cs +++ b/ErsatzTV.Application/Channels/Mapper.cs @@ -16,6 +16,7 @@ internal static class Mapper GetLogo(channel), channel.PreferredAudioLanguageCode, channel.PreferredAudioTitle, + channel.ProgressMode, channel.StreamingMode, channel.WatermarkId, channel.FallbackFillerId, diff --git a/ErsatzTV.Application/ErsatzTV.Application.csproj b/ErsatzTV.Application/ErsatzTV.Application.csproj index 48709b16..58f05440 100644 --- a/ErsatzTV.Application/ErsatzTV.Application.csproj +++ b/ErsatzTV.Application/ErsatzTV.Application.csproj @@ -12,7 +12,7 @@ - + @@ -20,8 +20,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs index ad7f44aa..ca8e2a34 100644 --- a/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs +++ b/ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs @@ -37,6 +37,10 @@ public class CreateFloodPlayoutHandler : IRequestHandler>, IBackgroundServiceRequest; diff --git a/ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs new file mode 100644 index 00000000..041b2988 --- /dev/null +++ b/ErsatzTV.Application/Playouts/Commands/TimeShiftOnDemandPlayoutHandler.cs @@ -0,0 +1,41 @@ +using ErsatzTV.Core; +using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.Scheduling; +using ErsatzTV.Infrastructure.Data; +using ErsatzTV.Infrastructure.Extensions; +using Microsoft.EntityFrameworkCore; + +namespace ErsatzTV.Application.Playouts; + +public class TimeShiftOnDemandPlayoutHandler( + IPlayoutTimeShifter playoutTimeShifter, + IDbContextFactory dbContextFactory) + : IRequestHandler> +{ + public async Task> Handle(TimeShiftOnDemandPlayout request, CancellationToken cancellationToken) + { + try + { + await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); + + Option maybePlayout = await dbContext.Playouts + .Include(p => p.Channel) + .Include(p => p.Items) + .Include(p => p.Anchor) + .Include(p => p.ProgramScheduleAnchors) + .SelectOneAsync(p => p.Channel.Number, p => p.Channel.Number == request.ChannelNumber); + + foreach (Playout playout in maybePlayout) + { + playoutTimeShifter.TimeShift(playout, request.Now, request.Force); + await dbContext.SaveChangesAsync(cancellationToken); + } + + return Option.None; + } + catch (Exception ex) + { + return BaseError.New(ex.Message); + } + } +} diff --git a/ErsatzTV.Application/Playouts/Commands/UpdateExternalJsonPlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/UpdateExternalJsonPlayoutHandler.cs index d76e8fe2..588737fd 100644 --- a/ErsatzTV.Application/Playouts/Commands/UpdateExternalJsonPlayoutHandler.cs +++ b/ErsatzTV.Application/Playouts/Commands/UpdateExternalJsonPlayoutHandler.cs @@ -49,9 +49,10 @@ public class playout.ProgramSchedulePlayoutType, playout.Channel.Name, playout.Channel.Number, + playout.Channel.ProgressMode, playout.ProgramSchedule?.Name ?? string.Empty, playout.ExternalJsonFile, - Optional(playout.DailyRebuildTime)); + playout.DailyRebuildTime); } private static Task> Validate( diff --git a/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpoint.cs b/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpoint.cs new file mode 100644 index 00000000..32320fcf --- /dev/null +++ b/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpoint.cs @@ -0,0 +1,4 @@ +namespace ErsatzTV.Application.Playouts; + +public record UpdateOnDemandCheckpoint(string ChannelNumber, DateTimeOffset Checkpoint) + : IRequest; diff --git a/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpointHandler.cs b/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpointHandler.cs new file mode 100644 index 00000000..3694fa8f --- /dev/null +++ b/ErsatzTV.Application/Playouts/Commands/UpdateOnDemandCheckpointHandler.cs @@ -0,0 +1,62 @@ +using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.Repositories; +using ErsatzTV.Infrastructure.Data; +using ErsatzTV.Infrastructure.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace ErsatzTV.Application.Playouts; + +public class UpdateOnDemandCheckpointHandler( + IDbContextFactory dbContextFactory, + IConfigElementRepository configElementRepository, + ILogger logger) + : IRequestHandler +{ + public async Task Handle(UpdateOnDemandCheckpoint request, CancellationToken cancellationToken) + { + await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); + + Option maybePlayout = await dbContext.Playouts + .Include(p => p.Channel) + .Include(p => p.Items) + .SelectOneAsync(p => p.Channel.Number, p => p.Channel.Number == request.ChannelNumber); + + foreach (Playout playout in maybePlayout) + { + if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand) + { + return; + } + + int timeout = await (await configElementRepository.GetValue(ConfigElementKey.FFmpegSegmenterTimeout)) + .IfNoneAsync(60); + + // don't move checkpoint back in time + DateTimeOffset newCheckpoint = request.Checkpoint - TimeSpan.FromSeconds(timeout); + if (newCheckpoint > playout.OnDemandCheckpoint) + { + playout.OnDemandCheckpoint = newCheckpoint; + } + + // don't checkpoint before the first item + // this could happen if you watch a new playout for less time than the segmenter timeout + if (playout.Items.Count > 0) + { + DateTimeOffset minStart = playout.Items.Min(p => p.StartOffset); + if (playout.OnDemandCheckpoint < minStart) + { + playout.OnDemandCheckpoint = minStart; + } + } + + logger.LogDebug( + "Updating on demand checkpoint for channel {Number} - {Name} to {Checkpoint}", + playout.Channel.Number, + playout.Channel.Name, + playout.OnDemandCheckpoint); + + await dbContext.SaveChangesAsync(cancellationToken); + } + } +} diff --git a/ErsatzTV.Application/Playouts/Commands/UpdatePlayoutHandler.cs b/ErsatzTV.Application/Playouts/Commands/UpdatePlayoutHandler.cs index 47b37822..ea2bfa7e 100644 --- a/ErsatzTV.Application/Playouts/Commands/UpdatePlayoutHandler.cs +++ b/ErsatzTV.Application/Playouts/Commands/UpdatePlayoutHandler.cs @@ -41,9 +41,10 @@ public class UpdatePlayoutHandler : IRequestHandler> Validate(TvContext dbContext, UpdatePlayout request) => diff --git a/ErsatzTV.Application/Playouts/PlayoutNameViewModel.cs b/ErsatzTV.Application/Playouts/PlayoutNameViewModel.cs index c7ad3c85..8163b942 100644 --- a/ErsatzTV.Application/Playouts/PlayoutNameViewModel.cs +++ b/ErsatzTV.Application/Playouts/PlayoutNameViewModel.cs @@ -7,6 +7,10 @@ public record PlayoutNameViewModel( ProgramSchedulePlayoutType PlayoutType, string ChannelName, string ChannelNumber, + ChannelProgressMode ProgressMode, string ScheduleName, string ExternalJsonFile, - Option DailyRebuildTime); + TimeSpan? DbDailyRebuildTime) +{ + public Option DailyRebuildTime => Optional(DbDailyRebuildTime); +} diff --git a/ErsatzTV.Application/Playouts/Queries/GetAllPlayoutsHandler.cs b/ErsatzTV.Application/Playouts/Queries/GetAllPlayoutsHandler.cs index 7c84f28c..7f3f5f02 100644 --- a/ErsatzTV.Application/Playouts/Queries/GetAllPlayoutsHandler.cs +++ b/ErsatzTV.Application/Playouts/Queries/GetAllPlayoutsHandler.cs @@ -25,9 +25,10 @@ public class GetAllPlayoutsHandler : IRequestHandler - + @@ -24,9 +24,9 @@ - + - + diff --git a/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs b/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs index 48b20134..40886bb8 100644 --- a/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs +++ b/ErsatzTV.Core.Tests/Scheduling/PlayoutBuilderTests.cs @@ -558,6 +558,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -657,6 +658,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -804,6 +806,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -909,6 +912,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1023,6 +1027,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1130,6 +1135,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1241,6 +1247,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1357,6 +1364,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1462,6 +1470,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1578,6 +1587,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1705,6 +1715,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1824,6 +1835,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -1903,6 +1915,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -2118,6 +2131,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -2609,6 +2623,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -2723,6 +2738,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -2837,6 +2853,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, fakeRepository, televisionRepo, @@ -2946,6 +2963,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, collectionRepo, televisionRepo, @@ -3001,6 +3019,7 @@ public class PlayoutBuilderTests Substitute.For(); ILocalFileSystem localFileSystem = Substitute.For(); var builder = new PlayoutBuilder( + Substitute.For(), configRepo, collectionRepo, televisionRepo, diff --git a/ErsatzTV.Core.Tests/Scheduling/ScheduleIntegrationTests.cs b/ErsatzTV.Core.Tests/Scheduling/ScheduleIntegrationTests.cs index 541ed249..c092de58 100644 --- a/ErsatzTV.Core.Tests/Scheduling/ScheduleIntegrationTests.cs +++ b/ErsatzTV.Core.Tests/Scheduling/ScheduleIntegrationTests.cs @@ -117,6 +117,7 @@ public class ScheduleIntegrationTests provider.GetRequiredService()); var builder = new PlayoutBuilder( + Substitute.For(), new ConfigElementRepository(factory), new MediaCollectionRepository(Substitute.For(), searchIndex, factory), new TelevisionRepository(factory, provider.GetRequiredService>()), @@ -287,6 +288,7 @@ public class ScheduleIntegrationTests DateTimeOffset finish = start.AddDays(2); var builder = new PlayoutBuilder( + Substitute.For(), new ConfigElementRepository(factory), new MediaCollectionRepository(Substitute.For(), Substitute.For(), factory), new TelevisionRepository(factory, provider.GetRequiredService>()), diff --git a/ErsatzTV.Core/Domain/Channel.cs b/ErsatzTV.Core/Domain/Channel.cs index 17b7d446..d4c13da8 100644 --- a/ErsatzTV.Core/Domain/Channel.cs +++ b/ErsatzTV.Core/Domain/Channel.cs @@ -28,4 +28,5 @@ public class Channel public ChannelSubtitleMode SubtitleMode { get; set; } public ChannelMusicVideoCreditsMode MusicVideoCreditsMode { get; set; } public string MusicVideoCreditsTemplate { get; set; } + public ChannelProgressMode ProgressMode { get; set; } } diff --git a/ErsatzTV.Core/Domain/ChannelProgressMode.cs b/ErsatzTV.Core/Domain/ChannelProgressMode.cs new file mode 100644 index 00000000..614fd6e1 --- /dev/null +++ b/ErsatzTV.Core/Domain/ChannelProgressMode.cs @@ -0,0 +1,7 @@ +namespace ErsatzTV.Core.Domain; + +public enum ChannelProgressMode +{ + Always = 0, + OnDemand = 1 +} diff --git a/ErsatzTV.Core/Domain/Playout.cs b/ErsatzTV.Core/Domain/Playout.cs index d0cc7d31..a2ba0467 100644 --- a/ErsatzTV.Core/Domain/Playout.cs +++ b/ErsatzTV.Core/Domain/Playout.cs @@ -22,4 +22,5 @@ public class Playout public TimeSpan? DailyRebuildTime { get; set; } public int? DecoId { get; set; } public Deco Deco { get; set; } + public DateTimeOffset? OnDemandCheckpoint { get; set; } } diff --git a/ErsatzTV.Core/ErsatzTV.Core.csproj b/ErsatzTV.Core/ErsatzTV.Core.csproj index aef25a4e..b2e0c9de 100644 --- a/ErsatzTV.Core/ErsatzTV.Core.csproj +++ b/ErsatzTV.Core/ErsatzTV.Core.csproj @@ -12,21 +12,21 @@ - + - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/ErsatzTV.Core/Interfaces/Scheduling/IPlayoutTimeShifter.cs b/ErsatzTV.Core/Interfaces/Scheduling/IPlayoutTimeShifter.cs new file mode 100644 index 00000000..78e8b6bc --- /dev/null +++ b/ErsatzTV.Core/Interfaces/Scheduling/IPlayoutTimeShifter.cs @@ -0,0 +1,8 @@ +using ErsatzTV.Core.Domain; + +namespace ErsatzTV.Core.Interfaces.Scheduling; + +public interface IPlayoutTimeShifter +{ + public void TimeShift(Playout playout, DateTimeOffset now, bool force); +} diff --git a/ErsatzTV.Core/Scheduling/PlayoutBuilder.cs b/ErsatzTV.Core/Scheduling/PlayoutBuilder.cs index 9e8ba9c6..9dbbd6c1 100644 --- a/ErsatzTV.Core/Scheduling/PlayoutBuilder.cs +++ b/ErsatzTV.Core/Scheduling/PlayoutBuilder.cs @@ -17,6 +17,7 @@ public class PlayoutBuilder : IPlayoutBuilder { private static readonly Random Random = new(); private readonly IArtistRepository _artistRepository; + private readonly IPlayoutTimeShifter _playoutTimeShifter; private readonly IConfigElementRepository _configElementRepository; private readonly ILocalFileSystem _localFileSystem; private readonly IMediaCollectionRepository _mediaCollectionRepository; @@ -26,6 +27,7 @@ public class PlayoutBuilder : IPlayoutBuilder private ILogger _logger; public PlayoutBuilder( + IPlayoutTimeShifter playoutTimeShifter, IConfigElementRepository configElementRepository, IMediaCollectionRepository mediaCollectionRepository, ITelevisionRepository televisionRepository, @@ -34,6 +36,7 @@ public class PlayoutBuilder : IPlayoutBuilder ILocalFileSystem localFileSystem, ILogger logger) { + _playoutTimeShifter = playoutTimeShifter; _configElementRepository = configElementRepository; _mediaCollectionRepository = mediaCollectionRepository; _televisionRepository = televisionRepository; @@ -79,6 +82,12 @@ public class PlayoutBuilder : IPlayoutBuilder // return await Build(playout, mode, parameters with { Start = parameters.Start.AddDays(-2) }); // } + // time shift on demand channel if needed + if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand && mode is not PlayoutBuildMode.Reset) + { + _playoutTimeShifter.TimeShift(playout, parameters.Start, false); + } + return await Build(playout, mode, parameters, cancellationToken); } @@ -238,6 +247,13 @@ public class PlayoutBuilder : IPlayoutBuilder playout.Items.Clear(); playout.Anchor = null; playout.ProgramScheduleAnchors.Clear(); + playout.OnDemandCheckpoint = null; + + // don't trim start for on demand channels, we want to time shift it all forward + if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand) + { + TrimStart = false; + } await BuildPlayoutItems( playout, @@ -247,6 +263,12 @@ public class PlayoutBuilder : IPlayoutBuilder true, cancellationToken); + // time shift on demand channel if needed + if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand) + { + _playoutTimeShifter.TimeShift(playout, parameters.Start, false); + } + return playout; } @@ -391,20 +413,24 @@ public class PlayoutBuilder : IPlayoutBuilder playout.Items.RemoveAll(old => old.FinishOffset < trimBefore); } - // check for future items that aren't grouped inside range - var futureItems = playout.Items.Filter(i => i.StartOffset > trimAfter).ToList(); - foreach (PlayoutItem futureItem in futureItems) + // on demand channels end up with slightly more than expected due to time shifting from midnight to first build + if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand) { - if (playout.Items.All(i => i == futureItem || i.GuideGroup != futureItem.GuideGroup)) + // check for future items that aren't grouped inside range + var futureItems = playout.Items.Filter(i => i.StartOffset > trimAfter).ToList(); + foreach (PlayoutItem futureItem in futureItems) { - _logger.LogError( - "Playout item scheduled for {Time} after hard stop of {HardStop}", - futureItem.StartOffset, - trimAfter); + if (playout.Items.All(i => i == futureItem || i.GuideGroup != futureItem.GuideGroup)) + { + _logger.LogError( + "Playout item scheduled for {Time} after hard stop of {HardStop}", + futureItem.StartOffset, + trimAfter); - // it feels hacky to have to clean up a playlist like this, - // so only log the error, and leave the bad data to fail tests - // playout.Items.Remove(futureItem); + // it feels hacky to have to clean up a playlist like this, + // so only log the error, and leave the bad data to fail tests + // playout.Items.Remove(futureItem); + } } } @@ -425,6 +451,12 @@ public class PlayoutBuilder : IPlayoutBuilder playout.ProgramScheduleAlternates, playoutStart); + // on demand channels do NOT use alternate schedules + if (playout.Channel.ProgressMode is ChannelProgressMode.OnDemand) + { + activeSchedule = playout.ProgramSchedule; + } + // _logger.LogDebug("Active schedule is: {Schedule}", activeSchedule.Name); // random start points are disabled in some scenarios, so ensure it's enabled and active diff --git a/ErsatzTV.Core/Scheduling/PlayoutTimeShifter.cs b/ErsatzTV.Core/Scheduling/PlayoutTimeShifter.cs new file mode 100644 index 00000000..88c17471 --- /dev/null +++ b/ErsatzTV.Core/Scheduling/PlayoutTimeShifter.cs @@ -0,0 +1,90 @@ +using ErsatzTV.Core.Domain; +using ErsatzTV.Core.Interfaces.FFmpeg; +using ErsatzTV.Core.Interfaces.Scheduling; +using Microsoft.Extensions.Logging; + +namespace ErsatzTV.Core.Scheduling; + +public class PlayoutTimeShifter(IFFmpegSegmenterService segmenterService, ILogger logger) + : IPlayoutTimeShifter +{ + public void TimeShift(Playout playout, DateTimeOffset now, bool force) + { + if (playout.Channel.ProgressMode is not ChannelProgressMode.OnDemand) + { + return; + } + + if (!force && segmenterService.IsActive(playout.Channel.Number)) + { + logger.LogDebug( + "Will not time shift on demand playout that is active for channel {Number} - {Name}", + playout.Channel.Number, + playout.Channel.Name); + + return; + } + + if (playout.Items.Count == 0) + { + logger.LogDebug( + "Unable to time shift empty playout for channel {Number} - {Name}", + playout.Channel.Number, + playout.Channel.Name); + + return; + } + + if (playout.OnDemandCheckpoint is null) + { + logger.LogDebug( + "Time shifting unwatched playout for channel {Number} - {Name}", + playout.Channel.Number, + playout.Channel.Name); + + playout.OnDemandCheckpoint = playout.Items.Min(p => p.StartOffset); + } + + TimeSpan toOffset = now - playout.OnDemandCheckpoint.IfNone(now); + + logger.LogDebug( + "Time shifting playout for channel {Number} - {Name} forward by {Time}", + playout.Channel.Number, + playout.Channel.Name, + toOffset); + + // time shift items + foreach (PlayoutItem playoutItem in playout.Items) + { + playoutItem.Start += toOffset; + playoutItem.Finish += toOffset; + + if (playoutItem.GuideStart.HasValue) + { + playoutItem.GuideStart += toOffset; + } + + if (playoutItem.GuideFinish.HasValue) + { + playoutItem.GuideFinish += toOffset; + } + } + + // time shift anchors + foreach (PlayoutProgramScheduleAnchor anchor in playout.ProgramScheduleAnchors) + { + if (anchor.AnchorDate.HasValue) + { + anchor.AnchorDate += toOffset; + } + } + + // time shift anchor + if (playout.Anchor is not null) + { + playout.Anchor.NextStart += toOffset; + } + + playout.OnDemandCheckpoint = now; + } +} diff --git a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj index 99f772df..72d05c64 100644 --- a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj +++ b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj @@ -10,7 +10,7 @@ - + diff --git a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj index 14ac77c6..14d5d415 100644 --- a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj +++ b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj @@ -16,7 +16,7 @@ - + diff --git a/ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.Designer.cs b/ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.Designer.cs new file mode 100644 index 00000000..51aa4b68 --- /dev/null +++ b/ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.Designer.cs @@ -0,0 +1,5802 @@ +// +using System; +using ErsatzTV.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ErsatzTV.Infrastructure.MySql.Migrations +{ + [DbContext(typeof(TvContext))] + [Migration("20240716141648_Add_Channel_ProgressMode")] + partial class Add_Channel_ProgressMode + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("ArtworkId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("longtext"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ArtworkId") + .IsUnique(); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Actor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("Biography") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Disambiguation") + .HasColumnType("longtext"); + + b.Property("Formed") + .HasColumnType("longtext"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistId"); + + b.ToTable("ArtistMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("ArtworkKind") + .HasColumnType("int"); + + b.Property("BlurHash43") + .HasColumnType("longtext"); + + b.Property("BlurHash54") + .HasColumnType("longtext"); + + b.Property("BlurHash64") + .HasColumnType("longtext"); + + b.Property("ChannelId") + .HasColumnType("int"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.Property("SourcePath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ChannelId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Artwork", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Categories") + .HasColumnType("longtext"); + + b.Property("FFmpegProfileId") + .HasColumnType("int"); + + b.Property("FallbackFillerId") + .HasColumnType("int"); + + b.Property("Group") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("longtext") + .HasDefaultValue("ErsatzTV"); + + b.Property("MusicVideoCreditsMode") + .HasColumnType("int"); + + b.Property("MusicVideoCreditsTemplate") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Number") + .HasColumnType("varchar(255)"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("longtext"); + + b.Property("PreferredAudioTitle") + .HasColumnType("longtext"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("longtext"); + + b.Property("ProgressMode") + .HasColumnType("int"); + + b.Property("StreamingMode") + .HasColumnType("int"); + + b.Property("SubtitleMode") + .HasColumnType("int"); + + b.Property("UniqueId") + .HasColumnType("char(36)"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FFmpegProfileId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("Number") + .IsUnique(); + + b.HasIndex("WatermarkId"); + + b.ToTable("Channel", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ChannelWatermark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DurationSeconds") + .HasColumnType("int"); + + b.Property("FrequencyMinutes") + .HasColumnType("int"); + + b.Property("HorizontalMarginPercent") + .HasColumnType("int"); + + b.Property("Image") + .HasColumnType("longtext"); + + b.Property("ImageSource") + .HasColumnType("int"); + + b.Property("Location") + .HasColumnType("int"); + + b.Property("Mode") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Opacity") + .HasColumnType("int"); + + b.Property("PlaceWithinSourceContent") + .HasColumnType("tinyint(1)"); + + b.Property("Size") + .HasColumnType("int"); + + b.Property("VerticalMarginPercent") + .HasColumnType("int"); + + b.Property("WidthPercent") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ChannelWatermark", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("UseCustomPlaybackOrder") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Collection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("CustomIndex") + .HasColumnType("int"); + + b.HasKey("CollectionId", "MediaItemId"); + + b.HasIndex("MediaItemId"); + + b.ToTable("CollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ConfigElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Key") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("ConfigElement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Director", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasColumnType("longtext"); + + b.Property("EmbyMediaSourceId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EmbyMediaSourceId") + .HasColumnType("int"); + + b.Property("EmbyPath") + .HasColumnType("longtext"); + + b.Property("LocalPath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeId") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.ToTable("EpisodeMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowBFrames") + .HasColumnType("tinyint(1)"); + + b.Property("AudioBitrate") + .HasColumnType("int"); + + b.Property("AudioBufferSize") + .HasColumnType("int"); + + b.Property("AudioChannels") + .HasColumnType("int"); + + b.Property("AudioFormat") + .HasColumnType("int"); + + b.Property("AudioSampleRate") + .HasColumnType("int"); + + b.Property("BitDepth") + .HasColumnType("int"); + + b.Property("DeinterlaceVideo") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("HardwareAcceleration") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("NormalizeFramerate") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("NormalizeLoudnessMode") + .HasColumnType("int"); + + b.Property("QsvExtraHardwareFrames") + .HasColumnType("int"); + + b.Property("ResolutionId") + .HasColumnType("int"); + + b.Property("ScalingBehavior") + .HasColumnType("int"); + + b.Property("ThreadCount") + .HasColumnType("int"); + + b.Property("VaapiDevice") + .HasColumnType("longtext"); + + b.Property("VaapiDriver") + .HasColumnType("int"); + + b.Property("VideoBitrate") + .HasColumnType("int"); + + b.Property("VideoBufferSize") + .HasColumnType("int"); + + b.Property("VideoFormat") + .HasColumnType("int"); + + b.Property("VideoPreset") + .HasColumnType("longtext"); + + b.Property("VideoProfile") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ResolutionId"); + + b.ToTable("FFmpegProfile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowWatermarks") + .HasColumnType("tinyint(1)"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("Duration") + .HasColumnType("time(6)"); + + b.Property("FillerKind") + .HasColumnType("int"); + + b.Property("FillerMode") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("PadToNearestMinute") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("FillerPreset", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Genre"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DurationSeconds") + .HasColumnType("double"); + + b.Property("LibraryFolderId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId") + .IsUnique(); + + b.ToTable("ImageFolderDuration", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DurationSeconds") + .HasColumnType("double"); + + b.Property("ImageId") + .HasColumnType("int"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("ImageMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasColumnType("longtext"); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("int"); + + b.Property("JellyfinPath") + .HasColumnType("longtext"); + + b.Property("LocalPath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LanguageCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EnglishName") + .HasColumnType("longtext"); + + b.Property("FrenchName") + .HasColumnType("longtext"); + + b.Property("ThreeCode1") + .HasColumnType("longtext"); + + b.Property("ThreeCode2") + .HasColumnType("longtext"); + + b.Property("TwoCode") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("LanguageCode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LastScan") + .HasColumnType("datetime(6)"); + + b.Property("MediaKind") + .HasColumnType("int"); + + b.Property("MediaSourceId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MediaSourceId"); + + b.ToTable("Library", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("LibraryPathId") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.HasIndex("ParentId"); + + b.ToTable("LibraryFolder", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LastScan") + .HasColumnType("datetime(6)"); + + b.Property("LibraryId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("LibraryId"); + + b.ToTable("LibraryPath", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChapterId") + .HasColumnType("bigint"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("MediaVersionId") + .HasColumnType("int"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaChapter", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LibraryFolderId") + .HasColumnType("int"); + + b.Property("MediaVersionId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId"); + + b.HasIndex("MediaVersionId"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("MediaFile", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LibraryPathId") + .HasColumnType("int"); + + b.Property("State") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.ToTable("MediaItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.HasKey("Id"); + + b.ToTable("MediaSource", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AttachedPic") + .HasColumnType("tinyint(1)"); + + b.Property("BitsPerRawSample") + .HasColumnType("int"); + + b.Property("Channels") + .HasColumnType("int"); + + b.Property("Codec") + .HasColumnType("longtext"); + + b.Property("ColorPrimaries") + .HasColumnType("longtext"); + + b.Property("ColorRange") + .HasColumnType("longtext"); + + b.Property("ColorSpace") + .HasColumnType("longtext"); + + b.Property("ColorTransfer") + .HasColumnType("longtext"); + + b.Property("Default") + .HasColumnType("tinyint(1)"); + + b.Property("FileName") + .HasColumnType("longtext"); + + b.Property("Forced") + .HasColumnType("tinyint(1)"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("MediaStreamKind") + .HasColumnType("int"); + + b.Property("MediaVersionId") + .HasColumnType("int"); + + b.Property("MimeType") + .HasColumnType("longtext"); + + b.Property("PixelFormat") + .HasColumnType("longtext"); + + b.Property("Profile") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaStream", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DisplayAspectRatio") + .HasColumnType("longtext"); + + b.Property("Duration") + .HasColumnType("time(6)"); + + b.Property("EpisodeId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("ImageId") + .HasColumnType("int"); + + b.Property("MovieId") + .HasColumnType("int"); + + b.Property("MusicVideoId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoId") + .HasColumnType("int"); + + b.Property("RFrameRate") + .HasColumnType("longtext"); + + b.Property("SampleAspectRatio") + .HasColumnType("longtext"); + + b.Property("SongId") + .HasColumnType("int"); + + b.Property("VideoScanKind") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.HasIndex("ImageId"); + + b.HasIndex("MovieId"); + + b.HasIndex("MusicVideoId"); + + b.HasIndex("OtherVideoId"); + + b.HasIndex("SongId"); + + b.ToTable("MediaVersion", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("Guid") + .HasColumnType("longtext"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("MetadataGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Mood"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentRating") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("MovieId") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MovieId"); + + b.ToTable("MovieMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("MultiCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("ScheduleAsGroup") + .HasColumnType("tinyint(1)"); + + b.HasKey("MultiCollectionId", "CollectionId"); + + b.HasIndex("CollectionId"); + + b.ToTable("MultiCollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("ScheduleAsGroup") + .HasColumnType("tinyint(1)"); + + b.HasKey("MultiCollectionId", "SmartCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("MultiCollectionSmartItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoMetadataId"); + + b.ToTable("MusicVideoArtist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Album") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("MusicVideoId") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Track") + .HasColumnType("int"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoId"); + + b.ToTable("MusicVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentRating") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("OtherVideoId") + .HasColumnType("int"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OtherVideoId"); + + b.ToTable("OtherVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("PlaylistGroupId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlaylistGroupId", "Name") + .IsUnique(); + + b.ToTable("Playlist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("PlaylistGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("tinyint(1)"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlayAll") + .HasColumnType("tinyint(1)"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("PlaylistId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlaylistItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChannelId") + .HasColumnType("int"); + + b.Property("DailyRebuildTime") + .HasColumnType("time(6)"); + + b.Property("DecoId") + .HasColumnType("int"); + + b.Property("ExternalJsonFile") + .HasColumnType("longtext"); + + b.Property("ProgramScheduleId") + .HasColumnType("int"); + + b.Property("ProgramSchedulePlayoutType") + .HasColumnType("int"); + + b.Property("Seed") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("DecoId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("Playout", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockKey") + .HasColumnType("longtext"); + + b.Property("ChapterTitle") + .HasColumnType("longtext"); + + b.Property("CollectionEtag") + .HasColumnType("longtext"); + + b.Property("CollectionKey") + .HasColumnType("longtext"); + + b.Property("CustomTitle") + .HasColumnType("longtext"); + + b.Property("DisableWatermarks") + .HasColumnType("tinyint(1)"); + + b.Property("FillerKind") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime(6)"); + + b.Property("GuideFinish") + .HasColumnType("datetime(6)"); + + b.Property("GuideGroup") + .HasColumnType("int"); + + b.Property("GuideStart") + .HasColumnType("datetime(6)"); + + b.Property("InPoint") + .HasColumnType("time(6)"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("OutPoint") + .HasColumnType("time(6)"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("longtext"); + + b.Property("PreferredAudioTitle") + .HasColumnType("longtext"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("longtext"); + + b.Property("Start") + .HasColumnType("datetime(6)"); + + b.Property("SubtitleMode") + .HasColumnType("int"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("PlayoutItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AnchorDate") + .HasColumnType("datetime(6)"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("FakeCollectionKey") + .HasColumnType("longtext"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlaylistId") + .HasColumnType("int"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlayoutProgramScheduleAnchor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("ProgramScheduleItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleItemId"); + + b.ToTable("PlayoutScheduleItemFillGroupIndex", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PlexMediaSourceId") + .HasColumnType("int"); + + b.Property("Uri") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LocalPath") + .HasColumnType("longtext"); + + b.Property("PlexMediaSourceId") + .HasColumnType("int"); + + b.Property("PlexPath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("KeepMultiPartEpisodesTogether") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("RandomStartPoint") + .HasColumnType("tinyint(1)"); + + b.Property("ShuffleScheduleItems") + .HasColumnType("tinyint(1)"); + + b.Property("TreatCollectionsAsShows") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ProgramSchedule", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DaysOfMonth") + .HasColumnType("longtext"); + + b.Property("DaysOfWeek") + .HasColumnType("longtext"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MonthsOfYear") + .HasColumnType("longtext"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("ProgramScheduleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("ProgramScheduleAlternate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("CustomTitle") + .HasColumnType("longtext"); + + b.Property("FakeCollectionKey") + .HasColumnType("longtext"); + + b.Property("FallbackFillerId") + .HasColumnType("int"); + + b.Property("FillWithGroupMode") + .HasColumnType("int"); + + b.Property("GuideMode") + .HasColumnType("int"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MidRollFillerId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("PlaylistId") + .HasColumnType("int"); + + b.Property("PostRollFillerId") + .HasColumnType("int"); + + b.Property("PreRollFillerId") + .HasColumnType("int"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("longtext"); + + b.Property("PreferredAudioTitle") + .HasColumnType("longtext"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("longtext"); + + b.Property("ProgramScheduleId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("SubtitleMode") + .HasColumnType("int"); + + b.Property("TailFillerId") + .HasColumnType("int"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MidRollFillerId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PostRollFillerId"); + + b.HasIndex("PreRollFillerId"); + + b.HasIndex("ProgramScheduleId"); + + b.HasIndex("SmartCollectionId"); + + b.HasIndex("TailFillerId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("ProgramScheduleItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Resolution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IsCustom") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Resolution", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockGroupId") + .HasColumnType("int"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Minutes") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("StopScheduling") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BlockGroupId", "Name") + .IsUnique(); + + b.ToTable("Block", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("BlockGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockId") + .HasColumnType("int"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("tinyint(1)"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("BlockItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeadAirFallbackCollectionId") + .HasColumnType("int"); + + b.Property("DeadAirFallbackCollectionType") + .HasColumnType("int"); + + b.Property("DeadAirFallbackMediaItemId") + .HasColumnType("int"); + + b.Property("DeadAirFallbackMode") + .HasColumnType("int"); + + b.Property("DeadAirFallbackMultiCollectionId") + .HasColumnType("int"); + + b.Property("DeadAirFallbackSmartCollectionId") + .HasColumnType("int"); + + b.Property("DecoGroupId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.Property("WatermarkMode") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DeadAirFallbackCollectionId"); + + b.HasIndex("DeadAirFallbackMediaItemId"); + + b.HasIndex("DeadAirFallbackMultiCollectionId"); + + b.HasIndex("DeadAirFallbackSmartCollectionId"); + + b.HasIndex("WatermarkId"); + + b.HasIndex("DecoGroupId", "Name") + .IsUnique(); + + b.ToTable("Deco", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DecoTemplateGroupId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateGroupId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DecoId") + .HasColumnType("int"); + + b.Property("DecoTemplateId") + .HasColumnType("int"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.HasKey("Id"); + + b.HasIndex("DecoId"); + + b.HasIndex("DecoTemplateId"); + + b.ToTable("DecoTemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockId") + .HasColumnType("int"); + + b.Property("Details") + .HasColumnType("longtext"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("PlayoutId"); + + b.ToTable("PlayoutHistory", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DaysOfMonth") + .HasColumnType("longtext"); + + b.Property("DaysOfWeek") + .HasColumnType("longtext"); + + b.Property("DecoTemplateId") + .HasColumnType("int"); + + b.Property("EndDay") + .HasColumnType("int"); + + b.Property("EndMonth") + .HasColumnType("int"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("LimitToDateRange") + .HasColumnType("tinyint(1)"); + + b.Property("MonthsOfYear") + .HasColumnType("longtext"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("StartDay") + .HasColumnType("int"); + + b.Property("StartMonth") + .HasColumnType("int"); + + b.Property("TemplateId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("TemplateId"); + + b.ToTable("PlayoutTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("TemplateGroupId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("TemplateGroupId"); + + b.ToTable("Template", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("TemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockId") + .HasColumnType("int"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("TemplateId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("TemplateId"); + + b.ToTable("TemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("SeasonMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentRating") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("ShowId") + .HasColumnType("int"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ShowId"); + + b.ToTable("ShowMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Query") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SmartCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Album") + .HasColumnType("longtext"); + + b.Property("AlbumArtists") + .HasColumnType("longtext"); + + b.Property("Artists") + .HasColumnType("longtext"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SongId") + .HasColumnType("int"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Track") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SongId"); + + b.ToTable("SongMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Studio", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Style"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("Codec") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Default") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("Forced") + .HasColumnType("tinyint(1)"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("IsExtracted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.Property("SDH") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.Property("StreamIndex") + .HasColumnType("int"); + + b.Property("SubtitleKind") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Subtitle", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ExternalCollectionId") + .HasColumnType("longtext"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Tag"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ItemCount") + .HasColumnType("int"); + + b.Property("List") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("TraktId") + .HasColumnType("int"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("TraktList", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Episode") + .HasColumnType("int"); + + b.Property("Kind") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Season") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TraktId") + .HasColumnType("int"); + + b.Property("TraktListId") + .HasColumnType("int"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("TraktListId"); + + b.ToTable("TraktListItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Guid") + .HasColumnType("longtext"); + + b.Property("TraktListItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TraktListItemId"); + + b.ToTable("TraktListItemGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Writer", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EmbyLibraryId") + .HasColumnType("int"); + + b.Property("NetworkPath") + .HasColumnType("longtext"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("EmbyLibraryId"); + + b.ToTable("EmbyPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("JellyfinLibraryId") + .HasColumnType("int"); + + b.Property("NetworkPath") + .HasColumnType("longtext"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinLibraryId"); + + b.ToTable("JellyfinPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("ShouldSyncItems") + .HasColumnType("tinyint(1)"); + + b.ToTable("EmbyLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("ShouldSyncItems") + .HasColumnType("tinyint(1)"); + + b.ToTable("JellyfinLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.ToTable("LocalLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("ShouldSyncItems") + .HasColumnType("tinyint(1)"); + + b.ToTable("PlexLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaFile"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("PlexId") + .HasColumnType("int"); + + b.ToTable("PlexMediaFile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Artist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.HasIndex("SeasonId"); + + b.ToTable("Episode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Image", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Movie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.HasIndex("ArtistId"); + + b.ToTable("MusicVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("OtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("ShowId") + .HasColumnType("int"); + + b.HasIndex("ShowId"); + + b.ToTable("Season", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Show", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Song", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("datetime(6)"); + + b.Property("OperatingSystem") + .HasColumnType("longtext"); + + b.Property("ServerName") + .HasColumnType("longtext"); + + b.ToTable("EmbyMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("datetime(6)"); + + b.Property("OperatingSystem") + .HasColumnType("longtext"); + + b.Property("ServerName") + .HasColumnType("longtext"); + + b.ToTable("JellyfinMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.ToTable("LocalMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("ClientIdentifier") + .HasColumnType("longtext"); + + b.Property("LastCollectionsScan") + .HasColumnType("datetime(6)"); + + b.Property("Platform") + .HasColumnType("longtext"); + + b.Property("PlatformVersion") + .HasColumnType("longtext"); + + b.Property("ProductVersion") + .HasColumnType("longtext"); + + b.Property("ServerName") + .HasColumnType("longtext"); + + b.ToTable("PlexMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("DiscardToFillAttempts") + .HasColumnType("int"); + + b.Property("PlayoutDuration") + .HasColumnType("time(6)"); + + b.Property("TailMode") + .HasColumnType("int"); + + b.ToTable("ProgramScheduleDurationItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleFloodItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("Count") + .HasColumnType("int"); + + b.ToTable("ProgramScheduleMultipleItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleOneItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbyEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbyMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.OtherVideo"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexOtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbySeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbyShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Actors") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Artwork", "Artwork") + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Actor", "ArtworkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Actors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Actors") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Actors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Actors") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Actors") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Actors") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Artwork"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("ArtistMetadata") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Channel", null) + .WithMany("Artwork") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Artwork") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.HasOne("ErsatzTV.Core.Domain.FFmpegProfile", "FFmpegProfile") + .WithMany() + .HasForeignKey("FFmpegProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("FFmpegProfile"); + + b.Navigation("FallbackFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("CollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("CollectionItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Directors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Directors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("Connections") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", "Episode") + .WithMany("EpisodeMetadata") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Episode"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.HasOne("ErsatzTV.Core.Domain.Resolution", "Resolution") + .WithMany() + .HasForeignKey("ResolutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Resolution"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Genres") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Genres") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Genres") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Genres") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Genres") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Genres") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Genres") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithOne("ImageFolderDuration") + .HasForeignKey("ErsatzTV.Core.Domain.ImageFolderDuration", "LibraryFolderId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("LibraryFolder"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Image", "Image") + .WithMany("ImageMetadata") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("Connections") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", "MediaSource") + .WithMany("Libraries") + .HasForeignKey("MediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("LibraryFolders") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("LibraryPath"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", "Library") + .WithMany("Paths") + .HasForeignKey("LibraryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Library"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Chapters") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithMany("MediaFiles") + .HasForeignKey("LibraryFolderId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("MediaFiles") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryFolder"); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("MediaItems") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryPath"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Streams") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithMany("MediaVersions") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Image", null) + .WithMany("MediaVersions") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithMany("MediaVersions") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Song", null) + .WithMany("MediaVersions") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Guids") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Guids") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Guids") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Guids") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Guids") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Guids") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Guids") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Moods") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", "Movie") + .WithMany("MovieMetadata") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Movie"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("MultiCollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MultiCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artists") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", "MusicVideo") + .WithMany("MusicVideoMetadata") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MusicVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", "OtherVideo") + .WithMany("OtherVideoMetadata") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OtherVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlaylistGroup", "PlaylistGroup") + .WithMany("Playlists") + .HasForeignKey("PlaylistGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlaylistGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany("Items") + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.HasOne("ErsatzTV.Core.Domain.Channel", "Channel") + .WithMany("Playouts") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany("Playouts") + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Playouts") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 => + { + b1.Property("PlayoutId") + .HasColumnType("int"); + + b1.Property("DurationFinish") + .HasColumnType("datetime(6)"); + + b1.Property("InDurationFiller") + .HasColumnType("tinyint(1)"); + + b1.Property("InFlood") + .HasColumnType("tinyint(1)"); + + b1.Property("MultipleRemaining") + .HasColumnType("int"); + + b1.Property("NextGuideGroup") + .HasColumnType("int"); + + b1.Property("NextStart") + .HasColumnType("datetime(6)"); + + b1.HasKey("PlayoutId"); + + b1.ToTable("PlayoutAnchor", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutId"); + + b1.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "ScheduleItemsEnumeratorState", b2 => + { + b2.Property("PlayoutAnchorPlayoutId") + .HasColumnType("int"); + + b2.Property("Index") + .HasColumnType("int"); + + b2.Property("Seed") + .HasColumnType("int"); + + b2.HasKey("PlayoutAnchorPlayoutId"); + + b2.ToTable("ScheduleItemsEnumeratorState", (string)null); + + b2.WithOwner() + .HasForeignKey("PlayoutAnchorPlayoutId"); + }); + + b1.Navigation("ScheduleItemsEnumeratorState"); + }); + + b.Navigation("Anchor"); + + b.Navigation("Channel"); + + b.Navigation("Deco"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Items") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("MediaItem"); + + b.Navigation("Playout"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAnchors") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutProgramScheduleAnchorId") + .HasColumnType("int"); + + b1.Property("Index") + .HasColumnType("int"); + + b1.Property("Seed") + .HasColumnType("int"); + + b1.HasKey("PlayoutProgramScheduleAnchorId"); + + b1.ToTable("CollectionEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutProgramScheduleAnchorId"); + }); + + b.Navigation("Collection"); + + b.Navigation("EnumeratorState"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("Playout"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("FillGroupIndices") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", "ProgramScheduleItem") + .WithMany() + .HasForeignKey("ProgramScheduleItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutScheduleItemFillGroupIndexId") + .HasColumnType("int"); + + b1.Property("Index") + .HasColumnType("int"); + + b1.Property("Seed") + .HasColumnType("int"); + + b1.HasKey("PlayoutScheduleItemFillGroupIndexId"); + + b1.ToTable("FillGroupEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutScheduleItemFillGroupIndexId"); + }); + + b.Navigation("EnumeratorState"); + + b.Navigation("Playout"); + + b.Navigation("ProgramScheduleItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("Connections") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Playout"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "MidRollFiller") + .WithMany() + .HasForeignKey("MidRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PostRollFiller") + .WithMany() + .HasForeignKey("PostRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PreRollFiller") + .WithMany() + .HasForeignKey("PreRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Items") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "TailFiller") + .WithMany() + .HasForeignKey("TailFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Collection"); + + b.Navigation("FallbackFiller"); + + b.Navigation("MediaItem"); + + b.Navigation("MidRollFiller"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("PostRollFiller"); + + b.Navigation("PreRollFiller"); + + b.Navigation("ProgramSchedule"); + + b.Navigation("SmartCollection"); + + b.Navigation("TailFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.BlockGroup", "BlockGroup") + .WithMany("Blocks") + .HasForeignKey("BlockGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BlockGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("Items") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Block"); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "DeadAirFallbackCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "DeadAirFallbackMediaItem") + .WithMany() + .HasForeignKey("DeadAirFallbackMediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "DeadAirFallbackMultiCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackMultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "DeadAirFallbackSmartCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackSmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoGroup", "DecoGroup") + .WithMany("Decos") + .HasForeignKey("DecoGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("DeadAirFallbackCollection"); + + b.Navigation("DeadAirFallbackMediaItem"); + + b.Navigation("DeadAirFallbackMultiCollection"); + + b.Navigation("DeadAirFallbackSmartCollection"); + + b.Navigation("DecoGroup"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", "DecoTemplateGroup") + .WithMany("DecoTemplates") + .HasForeignKey("DecoTemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany() + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("Items") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Deco"); + + b.Navigation("DecoTemplate"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("PlayoutHistory") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("PlayoutHistory") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Playout"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("PlayoutTemplates") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Templates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("PlayoutTemplates") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplate"); + + b.Navigation("Playout"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", "TemplateGroup") + .WithMany("Templates") + .HasForeignKey("TemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("TemplateItems") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("Items") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("SeasonMetadata") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("ShowMetadata") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Song", "Song") + .WithMany("SongMetadata") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Song"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Studios") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Studios") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Studios") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Studios") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Studios") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Studios") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Studios") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Styles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Tags") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Tags") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Tags") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Tags") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Tags") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Tags") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Tags") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("TraktListItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.TraktList", "TraktList") + .WithMany("Items") + .HasForeignKey("TraktListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("TraktList"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.TraktListItem", "TraktListItem") + .WithMany("Guids") + .HasForeignKey("TraktListItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TraktListItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Writers") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Writers") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Writers") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("EmbyLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("JellyfinLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaFile", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaFile", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Artist", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Episode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Image", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Movie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("MusicVideos") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.MusicVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.OtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Season", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("Seasons") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Show", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Song", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemOne", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexOtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbySeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Moods"); + + b.Navigation("Studios"); + + b.Navigation("Styles"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Navigation("Artwork"); + + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("MultiCollectionItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Navigation("Paths"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Navigation("Children"); + + b.Navigation("ImageFolderDuration"); + + b.Navigation("MediaFiles"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Navigation("LibraryFolders"); + + b.Navigation("MediaItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("TraktListItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Navigation("Libraries"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Navigation("Chapters"); + + b.Navigation("MediaFiles"); + + b.Navigation("Streams"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Navigation("MultiCollectionItems"); + + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artists"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Navigation("Playlists"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Navigation("FillGroupIndices"); + + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("ProgramScheduleAlternates"); + + b.Navigation("ProgramScheduleAnchors"); + + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Navigation("Items"); + + b.Navigation("Playouts"); + + b.Navigation("ProgramScheduleAlternates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("TemplateItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Navigation("Blocks"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Navigation("Decos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Navigation("DecoTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Navigation("Guids"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.Navigation("ArtistMetadata"); + + b.Navigation("MusicVideos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.Navigation("EpisodeMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.Navigation("ImageMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MovieMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MusicVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("OtherVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.Navigation("Episodes"); + + b.Navigation("SeasonMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.Navigation("Seasons"); + + b.Navigation("ShowMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("SongMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.cs b/ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.cs new file mode 100644 index 00000000..81437825 --- /dev/null +++ b/ErsatzTV.Infrastructure.MySql/Migrations/20240716141648_Add_Channel_ProgressMode.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ErsatzTV.Infrastructure.MySql.Migrations +{ + /// + public partial class Add_Channel_ProgressMode : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ProgressMode", + table: "Channel", + type: "int", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProgressMode", + table: "Channel"); + } + } +} diff --git a/ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.Designer.cs b/ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.Designer.cs new file mode 100644 index 00000000..fd1eb991 --- /dev/null +++ b/ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.Designer.cs @@ -0,0 +1,5805 @@ +// +using System; +using ErsatzTV.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ErsatzTV.Infrastructure.MySql.Migrations +{ + [DbContext(typeof(TvContext))] + [Migration("20240716155846_Add_Playout_OnDemandCheckpoint")] + partial class Add_Playout_OnDemandCheckpoint + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("ArtworkId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Order") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("longtext"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ArtworkId") + .IsUnique(); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Actor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("Biography") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Disambiguation") + .HasColumnType("longtext"); + + b.Property("Formed") + .HasColumnType("longtext"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistId"); + + b.ToTable("ArtistMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("ArtworkKind") + .HasColumnType("int"); + + b.Property("BlurHash43") + .HasColumnType("longtext"); + + b.Property("BlurHash54") + .HasColumnType("longtext"); + + b.Property("BlurHash64") + .HasColumnType("longtext"); + + b.Property("ChannelId") + .HasColumnType("int"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.Property("SourcePath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ChannelId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Artwork", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Categories") + .HasColumnType("longtext"); + + b.Property("FFmpegProfileId") + .HasColumnType("int"); + + b.Property("FallbackFillerId") + .HasColumnType("int"); + + b.Property("Group") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("longtext") + .HasDefaultValue("ErsatzTV"); + + b.Property("MusicVideoCreditsMode") + .HasColumnType("int"); + + b.Property("MusicVideoCreditsTemplate") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Number") + .HasColumnType("varchar(255)"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("longtext"); + + b.Property("PreferredAudioTitle") + .HasColumnType("longtext"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("longtext"); + + b.Property("ProgressMode") + .HasColumnType("int"); + + b.Property("StreamingMode") + .HasColumnType("int"); + + b.Property("SubtitleMode") + .HasColumnType("int"); + + b.Property("UniqueId") + .HasColumnType("char(36)"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FFmpegProfileId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("Number") + .IsUnique(); + + b.HasIndex("WatermarkId"); + + b.ToTable("Channel", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ChannelWatermark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DurationSeconds") + .HasColumnType("int"); + + b.Property("FrequencyMinutes") + .HasColumnType("int"); + + b.Property("HorizontalMarginPercent") + .HasColumnType("int"); + + b.Property("Image") + .HasColumnType("longtext"); + + b.Property("ImageSource") + .HasColumnType("int"); + + b.Property("Location") + .HasColumnType("int"); + + b.Property("Mode") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Opacity") + .HasColumnType("int"); + + b.Property("PlaceWithinSourceContent") + .HasColumnType("tinyint(1)"); + + b.Property("Size") + .HasColumnType("int"); + + b.Property("VerticalMarginPercent") + .HasColumnType("int"); + + b.Property("WidthPercent") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("ChannelWatermark", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("UseCustomPlaybackOrder") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("Collection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("CustomIndex") + .HasColumnType("int"); + + b.HasKey("CollectionId", "MediaItemId"); + + b.HasIndex("MediaItemId"); + + b.ToTable("CollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ConfigElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Key") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("ConfigElement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Director", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasColumnType("longtext"); + + b.Property("EmbyMediaSourceId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EmbyMediaSourceId") + .HasColumnType("int"); + + b.Property("EmbyPath") + .HasColumnType("longtext"); + + b.Property("LocalPath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeId") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.ToTable("EpisodeMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowBFrames") + .HasColumnType("tinyint(1)"); + + b.Property("AudioBitrate") + .HasColumnType("int"); + + b.Property("AudioBufferSize") + .HasColumnType("int"); + + b.Property("AudioChannels") + .HasColumnType("int"); + + b.Property("AudioFormat") + .HasColumnType("int"); + + b.Property("AudioSampleRate") + .HasColumnType("int"); + + b.Property("BitDepth") + .HasColumnType("int"); + + b.Property("DeinterlaceVideo") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(true); + + b.Property("HardwareAcceleration") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("NormalizeFramerate") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("NormalizeLoudnessMode") + .HasColumnType("int"); + + b.Property("QsvExtraHardwareFrames") + .HasColumnType("int"); + + b.Property("ResolutionId") + .HasColumnType("int"); + + b.Property("ScalingBehavior") + .HasColumnType("int"); + + b.Property("ThreadCount") + .HasColumnType("int"); + + b.Property("VaapiDevice") + .HasColumnType("longtext"); + + b.Property("VaapiDriver") + .HasColumnType("int"); + + b.Property("VideoBitrate") + .HasColumnType("int"); + + b.Property("VideoBufferSize") + .HasColumnType("int"); + + b.Property("VideoFormat") + .HasColumnType("int"); + + b.Property("VideoPreset") + .HasColumnType("longtext"); + + b.Property("VideoProfile") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ResolutionId"); + + b.ToTable("FFmpegProfile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AllowWatermarks") + .HasColumnType("tinyint(1)"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("Duration") + .HasColumnType("time(6)"); + + b.Property("FillerKind") + .HasColumnType("int"); + + b.Property("FillerMode") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("PadToNearestMinute") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("FillerPreset", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Genre"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DurationSeconds") + .HasColumnType("double"); + + b.Property("LibraryFolderId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId") + .IsUnique(); + + b.ToTable("ImageFolderDuration", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DurationSeconds") + .HasColumnType("double"); + + b.Property("ImageId") + .HasColumnType("int"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("ImageMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Address") + .HasColumnType("longtext"); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("int"); + + b.Property("JellyfinPath") + .HasColumnType("longtext"); + + b.Property("LocalPath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LanguageCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EnglishName") + .HasColumnType("longtext"); + + b.Property("FrenchName") + .HasColumnType("longtext"); + + b.Property("ThreeCode1") + .HasColumnType("longtext"); + + b.Property("ThreeCode2") + .HasColumnType("longtext"); + + b.Property("TwoCode") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("LanguageCode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LastScan") + .HasColumnType("datetime(6)"); + + b.Property("MediaKind") + .HasColumnType("int"); + + b.Property("MediaSourceId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MediaSourceId"); + + b.ToTable("Library", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("LibraryPathId") + .HasColumnType("int"); + + b.Property("ParentId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.HasIndex("ParentId"); + + b.ToTable("LibraryFolder", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LastScan") + .HasColumnType("datetime(6)"); + + b.Property("LibraryId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("LibraryId"); + + b.ToTable("LibraryPath", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChapterId") + .HasColumnType("bigint"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("MediaVersionId") + .HasColumnType("int"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaChapter", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LibraryFolderId") + .HasColumnType("int"); + + b.Property("MediaVersionId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId"); + + b.HasIndex("MediaVersionId"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("MediaFile", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LibraryPathId") + .HasColumnType("int"); + + b.Property("State") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.ToTable("MediaItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.HasKey("Id"); + + b.ToTable("MediaSource", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AttachedPic") + .HasColumnType("tinyint(1)"); + + b.Property("BitsPerRawSample") + .HasColumnType("int"); + + b.Property("Channels") + .HasColumnType("int"); + + b.Property("Codec") + .HasColumnType("longtext"); + + b.Property("ColorPrimaries") + .HasColumnType("longtext"); + + b.Property("ColorRange") + .HasColumnType("longtext"); + + b.Property("ColorSpace") + .HasColumnType("longtext"); + + b.Property("ColorTransfer") + .HasColumnType("longtext"); + + b.Property("Default") + .HasColumnType("tinyint(1)"); + + b.Property("FileName") + .HasColumnType("longtext"); + + b.Property("Forced") + .HasColumnType("tinyint(1)"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("MediaStreamKind") + .HasColumnType("int"); + + b.Property("MediaVersionId") + .HasColumnType("int"); + + b.Property("MimeType") + .HasColumnType("longtext"); + + b.Property("PixelFormat") + .HasColumnType("longtext"); + + b.Property("Profile") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaStream", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DisplayAspectRatio") + .HasColumnType("longtext"); + + b.Property("Duration") + .HasColumnType("time(6)"); + + b.Property("EpisodeId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("ImageId") + .HasColumnType("int"); + + b.Property("MovieId") + .HasColumnType("int"); + + b.Property("MusicVideoId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoId") + .HasColumnType("int"); + + b.Property("RFrameRate") + .HasColumnType("longtext"); + + b.Property("SampleAspectRatio") + .HasColumnType("longtext"); + + b.Property("SongId") + .HasColumnType("int"); + + b.Property("VideoScanKind") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.HasIndex("ImageId"); + + b.HasIndex("MovieId"); + + b.HasIndex("MusicVideoId"); + + b.HasIndex("OtherVideoId"); + + b.HasIndex("SongId"); + + b.ToTable("MediaVersion", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("Guid") + .HasColumnType("longtext"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("MetadataGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Mood"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentRating") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("MovieId") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MovieId"); + + b.ToTable("MovieMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("MultiCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("ScheduleAsGroup") + .HasColumnType("tinyint(1)"); + + b.HasKey("MultiCollectionId", "CollectionId"); + + b.HasIndex("CollectionId"); + + b.ToTable("MultiCollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("ScheduleAsGroup") + .HasColumnType("tinyint(1)"); + + b.HasKey("MultiCollectionId", "SmartCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("MultiCollectionSmartItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoMetadataId"); + + b.ToTable("MusicVideoArtist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Album") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("MusicVideoId") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Track") + .HasColumnType("int"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoId"); + + b.ToTable("MusicVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentRating") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("OtherVideoId") + .HasColumnType("int"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OtherVideoId"); + + b.ToTable("OtherVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("PlaylistGroupId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlaylistGroupId", "Name") + .IsUnique(); + + b.ToTable("Playlist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("PlaylistGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("tinyint(1)"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlayAll") + .HasColumnType("tinyint(1)"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("PlaylistId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlaylistItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ChannelId") + .HasColumnType("int"); + + b.Property("DailyRebuildTime") + .HasColumnType("time(6)"); + + b.Property("DecoId") + .HasColumnType("int"); + + b.Property("ExternalJsonFile") + .HasColumnType("longtext"); + + b.Property("OnDemandCheckpoint") + .HasColumnType("datetime(6)"); + + b.Property("ProgramScheduleId") + .HasColumnType("int"); + + b.Property("ProgramSchedulePlayoutType") + .HasColumnType("int"); + + b.Property("Seed") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("DecoId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("Playout", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockKey") + .HasColumnType("longtext"); + + b.Property("ChapterTitle") + .HasColumnType("longtext"); + + b.Property("CollectionEtag") + .HasColumnType("longtext"); + + b.Property("CollectionKey") + .HasColumnType("longtext"); + + b.Property("CustomTitle") + .HasColumnType("longtext"); + + b.Property("DisableWatermarks") + .HasColumnType("tinyint(1)"); + + b.Property("FillerKind") + .HasColumnType("int"); + + b.Property("Finish") + .HasColumnType("datetime(6)"); + + b.Property("GuideFinish") + .HasColumnType("datetime(6)"); + + b.Property("GuideGroup") + .HasColumnType("int"); + + b.Property("GuideStart") + .HasColumnType("datetime(6)"); + + b.Property("InPoint") + .HasColumnType("time(6)"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("OutPoint") + .HasColumnType("time(6)"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("longtext"); + + b.Property("PreferredAudioTitle") + .HasColumnType("longtext"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("longtext"); + + b.Property("Start") + .HasColumnType("datetime(6)"); + + b.Property("SubtitleMode") + .HasColumnType("int"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("PlayoutItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("AnchorDate") + .HasColumnType("datetime(6)"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("FakeCollectionKey") + .HasColumnType("longtext"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlaylistId") + .HasColumnType("int"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlayoutProgramScheduleAnchor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("ProgramScheduleItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleItemId"); + + b.ToTable("PlayoutScheduleItemFillGroupIndex", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PlexMediaSourceId") + .HasColumnType("int"); + + b.Property("Uri") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("LocalPath") + .HasColumnType("longtext"); + + b.Property("PlexMediaSourceId") + .HasColumnType("int"); + + b.Property("PlexPath") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("KeepMultiPartEpisodesTogether") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("RandomStartPoint") + .HasColumnType("tinyint(1)"); + + b.Property("ShuffleScheduleItems") + .HasColumnType("tinyint(1)"); + + b.Property("TreatCollectionsAsShows") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ProgramSchedule", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DaysOfMonth") + .HasColumnType("longtext"); + + b.Property("DaysOfWeek") + .HasColumnType("longtext"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MonthsOfYear") + .HasColumnType("longtext"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("ProgramScheduleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("ProgramScheduleAlternate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("CustomTitle") + .HasColumnType("longtext"); + + b.Property("FakeCollectionKey") + .HasColumnType("longtext"); + + b.Property("FallbackFillerId") + .HasColumnType("int"); + + b.Property("FillWithGroupMode") + .HasColumnType("int"); + + b.Property("GuideMode") + .HasColumnType("int"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MidRollFillerId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("PlaylistId") + .HasColumnType("int"); + + b.Property("PostRollFillerId") + .HasColumnType("int"); + + b.Property("PreRollFillerId") + .HasColumnType("int"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("longtext"); + + b.Property("PreferredAudioTitle") + .HasColumnType("longtext"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("longtext"); + + b.Property("ProgramScheduleId") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("SubtitleMode") + .HasColumnType("int"); + + b.Property("TailFillerId") + .HasColumnType("int"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MidRollFillerId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PostRollFillerId"); + + b.HasIndex("PreRollFillerId"); + + b.HasIndex("ProgramScheduleId"); + + b.HasIndex("SmartCollectionId"); + + b.HasIndex("TailFillerId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("ProgramScheduleItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Resolution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IsCustom") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Resolution", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockGroupId") + .HasColumnType("int"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Minutes") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("StopScheduling") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BlockGroupId", "Name") + .IsUnique(); + + b.ToTable("Block", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("BlockGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockId") + .HasColumnType("int"); + + b.Property("CollectionId") + .HasColumnType("int"); + + b.Property("CollectionType") + .HasColumnType("int"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("tinyint(1)"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("MultiCollectionId") + .HasColumnType("int"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("SmartCollectionId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("BlockItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DeadAirFallbackCollectionId") + .HasColumnType("int"); + + b.Property("DeadAirFallbackCollectionType") + .HasColumnType("int"); + + b.Property("DeadAirFallbackMediaItemId") + .HasColumnType("int"); + + b.Property("DeadAirFallbackMode") + .HasColumnType("int"); + + b.Property("DeadAirFallbackMultiCollectionId") + .HasColumnType("int"); + + b.Property("DeadAirFallbackSmartCollectionId") + .HasColumnType("int"); + + b.Property("DecoGroupId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("WatermarkId") + .HasColumnType("int"); + + b.Property("WatermarkMode") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DeadAirFallbackCollectionId"); + + b.HasIndex("DeadAirFallbackMediaItemId"); + + b.HasIndex("DeadAirFallbackMultiCollectionId"); + + b.HasIndex("DeadAirFallbackSmartCollectionId"); + + b.HasIndex("WatermarkId"); + + b.HasIndex("DecoGroupId", "Name") + .IsUnique(); + + b.ToTable("Deco", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DecoTemplateGroupId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateGroupId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DecoId") + .HasColumnType("int"); + + b.Property("DecoTemplateId") + .HasColumnType("int"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.HasKey("Id"); + + b.HasIndex("DecoId"); + + b.HasIndex("DecoTemplateId"); + + b.ToTable("DecoTemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockId") + .HasColumnType("int"); + + b.Property("Details") + .HasColumnType("longtext"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("PlaybackOrder") + .HasColumnType("int"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("When") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("PlayoutId"); + + b.ToTable("PlayoutHistory", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("DaysOfMonth") + .HasColumnType("longtext"); + + b.Property("DaysOfWeek") + .HasColumnType("longtext"); + + b.Property("DecoTemplateId") + .HasColumnType("int"); + + b.Property("EndDay") + .HasColumnType("int"); + + b.Property("EndMonth") + .HasColumnType("int"); + + b.Property("Index") + .HasColumnType("int"); + + b.Property("LimitToDateRange") + .HasColumnType("tinyint(1)"); + + b.Property("MonthsOfYear") + .HasColumnType("longtext"); + + b.Property("PlayoutId") + .HasColumnType("int"); + + b.Property("StartDay") + .HasColumnType("int"); + + b.Property("StartMonth") + .HasColumnType("int"); + + b.Property("TemplateId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("TemplateId"); + + b.ToTable("PlayoutTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("TemplateGroupId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("TemplateGroupId"); + + b.ToTable("Template", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("TemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("BlockId") + .HasColumnType("int"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("TemplateId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("TemplateId"); + + b.ToTable("TemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("SeasonMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ContentRating") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("Outline") + .HasColumnType("longtext"); + + b.Property("Plot") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("ShowId") + .HasColumnType("int"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Tagline") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ShowId"); + + b.ToTable("ShowMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("Query") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SmartCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Album") + .HasColumnType("longtext"); + + b.Property("AlbumArtists") + .HasColumnType("longtext"); + + b.Property("Artists") + .HasColumnType("longtext"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("MetadataKind") + .HasColumnType("int"); + + b.Property("OriginalTitle") + .HasColumnType("longtext"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("SongId") + .HasColumnType("int"); + + b.Property("SortTitle") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Track") + .HasColumnType("longtext"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("SongId"); + + b.ToTable("SongMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Studio", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Style"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("Codec") + .HasColumnType("longtext"); + + b.Property("DateAdded") + .HasColumnType("datetime(6)"); + + b.Property("DateUpdated") + .HasColumnType("datetime(6)"); + + b.Property("Default") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("Forced") + .HasColumnType("tinyint(1)"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("IsExtracted") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.Property("SDH") + .ValueGeneratedOnAdd() + .HasColumnType("tinyint(1)") + .HasDefaultValue(false); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.Property("StreamIndex") + .HasColumnType("int"); + + b.Property("SubtitleKind") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Subtitle", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ArtistMetadataId") + .HasColumnType("int"); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("ExternalCollectionId") + .HasColumnType("longtext"); + + b.Property("ImageMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.Property("SeasonMetadataId") + .HasColumnType("int"); + + b.Property("ShowMetadataId") + .HasColumnType("int"); + + b.Property("SongMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Tag"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ItemCount") + .HasColumnType("int"); + + b.Property("List") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("TraktId") + .HasColumnType("int"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("TraktList", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Episode") + .HasColumnType("int"); + + b.Property("Kind") + .HasColumnType("int"); + + b.Property("MediaItemId") + .HasColumnType("int"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Season") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TraktId") + .HasColumnType("int"); + + b.Property("TraktListId") + .HasColumnType("int"); + + b.Property("Year") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("TraktListId"); + + b.ToTable("TraktListItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("Guid") + .HasColumnType("longtext"); + + b.Property("TraktListItemId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("TraktListItemId"); + + b.ToTable("TraktListItemGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EpisodeMetadataId") + .HasColumnType("int"); + + b.Property("MovieMetadataId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Writer", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("EmbyLibraryId") + .HasColumnType("int"); + + b.Property("NetworkPath") + .HasColumnType("longtext"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("EmbyLibraryId"); + + b.ToTable("EmbyPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("JellyfinLibraryId") + .HasColumnType("int"); + + b.Property("NetworkPath") + .HasColumnType("longtext"); + + b.Property("Path") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinLibraryId"); + + b.ToTable("JellyfinPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("ShouldSyncItems") + .HasColumnType("tinyint(1)"); + + b.ToTable("EmbyLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.Property("ShouldSyncItems") + .HasColumnType("tinyint(1)"); + + b.ToTable("JellyfinLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.ToTable("LocalLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("ShouldSyncItems") + .HasColumnType("tinyint(1)"); + + b.ToTable("PlexLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaFile"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("PlexId") + .HasColumnType("int"); + + b.ToTable("PlexMediaFile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Artist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.HasIndex("SeasonId"); + + b.ToTable("Episode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Image", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Movie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.HasIndex("ArtistId"); + + b.ToTable("MusicVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("OtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("ShowId") + .HasColumnType("int"); + + b.HasIndex("ShowId"); + + b.ToTable("Season", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Show", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Song", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("datetime(6)"); + + b.Property("OperatingSystem") + .HasColumnType("longtext"); + + b.Property("ServerName") + .HasColumnType("longtext"); + + b.ToTable("EmbyMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("datetime(6)"); + + b.Property("OperatingSystem") + .HasColumnType("longtext"); + + b.Property("ServerName") + .HasColumnType("longtext"); + + b.ToTable("JellyfinMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.ToTable("LocalMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("ClientIdentifier") + .HasColumnType("longtext"); + + b.Property("LastCollectionsScan") + .HasColumnType("datetime(6)"); + + b.Property("Platform") + .HasColumnType("longtext"); + + b.Property("PlatformVersion") + .HasColumnType("longtext"); + + b.Property("ProductVersion") + .HasColumnType("longtext"); + + b.Property("ServerName") + .HasColumnType("longtext"); + + b.ToTable("PlexMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("DiscardToFillAttempts") + .HasColumnType("int"); + + b.Property("PlayoutDuration") + .HasColumnType("time(6)"); + + b.Property("TailMode") + .HasColumnType("int"); + + b.ToTable("ProgramScheduleDurationItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleFloodItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("Count") + .HasColumnType("int"); + + b.ToTable("ProgramScheduleMultipleItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleOneItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbyEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbyMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.OtherVideo"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexOtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbySeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("EmbyShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("ItemId") + .HasColumnType("longtext"); + + b.ToTable("JellyfinShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.ToTable("PlexShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Actors") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Artwork", "Artwork") + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Actor", "ArtworkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Actors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Actors") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Actors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Actors") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Actors") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Actors") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Artwork"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("ArtistMetadata") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Channel", null) + .WithMany("Artwork") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Artwork") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.HasOne("ErsatzTV.Core.Domain.FFmpegProfile", "FFmpegProfile") + .WithMany() + .HasForeignKey("FFmpegProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("FFmpegProfile"); + + b.Navigation("FallbackFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("CollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("CollectionItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Directors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Directors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("Connections") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", "Episode") + .WithMany("EpisodeMetadata") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Episode"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.HasOne("ErsatzTV.Core.Domain.Resolution", "Resolution") + .WithMany() + .HasForeignKey("ResolutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Resolution"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Genres") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Genres") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Genres") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Genres") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Genres") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Genres") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Genres") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithOne("ImageFolderDuration") + .HasForeignKey("ErsatzTV.Core.Domain.ImageFolderDuration", "LibraryFolderId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("LibraryFolder"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Image", "Image") + .WithMany("ImageMetadata") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("Connections") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", "MediaSource") + .WithMany("Libraries") + .HasForeignKey("MediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("LibraryFolders") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("LibraryPath"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", "Library") + .WithMany("Paths") + .HasForeignKey("LibraryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Library"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Chapters") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithMany("MediaFiles") + .HasForeignKey("LibraryFolderId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("MediaFiles") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryFolder"); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("MediaItems") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryPath"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Streams") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithMany("MediaVersions") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Image", null) + .WithMany("MediaVersions") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithMany("MediaVersions") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Song", null) + .WithMany("MediaVersions") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Guids") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Guids") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Guids") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Guids") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Guids") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Guids") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Guids") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Moods") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", "Movie") + .WithMany("MovieMetadata") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Movie"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("MultiCollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MultiCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artists") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", "MusicVideo") + .WithMany("MusicVideoMetadata") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MusicVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", "OtherVideo") + .WithMany("OtherVideoMetadata") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OtherVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlaylistGroup", "PlaylistGroup") + .WithMany("Playlists") + .HasForeignKey("PlaylistGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlaylistGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany("Items") + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.HasOne("ErsatzTV.Core.Domain.Channel", "Channel") + .WithMany("Playouts") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany("Playouts") + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Playouts") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 => + { + b1.Property("PlayoutId") + .HasColumnType("int"); + + b1.Property("DurationFinish") + .HasColumnType("datetime(6)"); + + b1.Property("InDurationFiller") + .HasColumnType("tinyint(1)"); + + b1.Property("InFlood") + .HasColumnType("tinyint(1)"); + + b1.Property("MultipleRemaining") + .HasColumnType("int"); + + b1.Property("NextGuideGroup") + .HasColumnType("int"); + + b1.Property("NextStart") + .HasColumnType("datetime(6)"); + + b1.HasKey("PlayoutId"); + + b1.ToTable("PlayoutAnchor", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutId"); + + b1.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "ScheduleItemsEnumeratorState", b2 => + { + b2.Property("PlayoutAnchorPlayoutId") + .HasColumnType("int"); + + b2.Property("Index") + .HasColumnType("int"); + + b2.Property("Seed") + .HasColumnType("int"); + + b2.HasKey("PlayoutAnchorPlayoutId"); + + b2.ToTable("ScheduleItemsEnumeratorState", (string)null); + + b2.WithOwner() + .HasForeignKey("PlayoutAnchorPlayoutId"); + }); + + b1.Navigation("ScheduleItemsEnumeratorState"); + }); + + b.Navigation("Anchor"); + + b.Navigation("Channel"); + + b.Navigation("Deco"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Items") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("MediaItem"); + + b.Navigation("Playout"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAnchors") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutProgramScheduleAnchorId") + .HasColumnType("int"); + + b1.Property("Index") + .HasColumnType("int"); + + b1.Property("Seed") + .HasColumnType("int"); + + b1.HasKey("PlayoutProgramScheduleAnchorId"); + + b1.ToTable("CollectionEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutProgramScheduleAnchorId"); + }); + + b.Navigation("Collection"); + + b.Navigation("EnumeratorState"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("Playout"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("FillGroupIndices") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", "ProgramScheduleItem") + .WithMany() + .HasForeignKey("ProgramScheduleItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutScheduleItemFillGroupIndexId") + .HasColumnType("int"); + + b1.Property("Index") + .HasColumnType("int"); + + b1.Property("Seed") + .HasColumnType("int"); + + b1.HasKey("PlayoutScheduleItemFillGroupIndexId"); + + b1.ToTable("FillGroupEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutScheduleItemFillGroupIndexId"); + }); + + b.Navigation("EnumeratorState"); + + b.Navigation("Playout"); + + b.Navigation("ProgramScheduleItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("Connections") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Playout"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "MidRollFiller") + .WithMany() + .HasForeignKey("MidRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PostRollFiller") + .WithMany() + .HasForeignKey("PostRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PreRollFiller") + .WithMany() + .HasForeignKey("PreRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Items") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "TailFiller") + .WithMany() + .HasForeignKey("TailFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Collection"); + + b.Navigation("FallbackFiller"); + + b.Navigation("MediaItem"); + + b.Navigation("MidRollFiller"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("PostRollFiller"); + + b.Navigation("PreRollFiller"); + + b.Navigation("ProgramSchedule"); + + b.Navigation("SmartCollection"); + + b.Navigation("TailFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.BlockGroup", "BlockGroup") + .WithMany("Blocks") + .HasForeignKey("BlockGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BlockGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("Items") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Block"); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "DeadAirFallbackCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "DeadAirFallbackMediaItem") + .WithMany() + .HasForeignKey("DeadAirFallbackMediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "DeadAirFallbackMultiCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackMultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "DeadAirFallbackSmartCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackSmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoGroup", "DecoGroup") + .WithMany("Decos") + .HasForeignKey("DecoGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("DeadAirFallbackCollection"); + + b.Navigation("DeadAirFallbackMediaItem"); + + b.Navigation("DeadAirFallbackMultiCollection"); + + b.Navigation("DeadAirFallbackSmartCollection"); + + b.Navigation("DecoGroup"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", "DecoTemplateGroup") + .WithMany("DecoTemplates") + .HasForeignKey("DecoTemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany() + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("Items") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Deco"); + + b.Navigation("DecoTemplate"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("PlayoutHistory") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("PlayoutHistory") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Playout"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("PlayoutTemplates") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Templates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("PlayoutTemplates") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplate"); + + b.Navigation("Playout"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", "TemplateGroup") + .WithMany("Templates") + .HasForeignKey("TemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("TemplateItems") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("Items") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("SeasonMetadata") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("ShowMetadata") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Song", "Song") + .WithMany("SongMetadata") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Song"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Studios") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Studios") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Studios") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Studios") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Studios") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Studios") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Studios") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Styles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Tags") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Tags") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Tags") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Tags") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Tags") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Tags") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Tags") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("TraktListItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.TraktList", "TraktList") + .WithMany("Items") + .HasForeignKey("TraktListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("TraktList"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.TraktListItem", "TraktListItem") + .WithMany("Guids") + .HasForeignKey("TraktListItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TraktListItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Writers") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Writers") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Writers") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("EmbyLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("JellyfinLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaFile", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaFile", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Artist", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Episode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Image", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Movie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("MusicVideos") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.MusicVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.OtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Season", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("Seasons") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Show", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Song", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemOne", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexOtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbySeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Moods"); + + b.Navigation("Studios"); + + b.Navigation("Styles"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Navigation("Artwork"); + + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("MultiCollectionItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Navigation("Paths"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Navigation("Children"); + + b.Navigation("ImageFolderDuration"); + + b.Navigation("MediaFiles"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Navigation("LibraryFolders"); + + b.Navigation("MediaItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("TraktListItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Navigation("Libraries"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Navigation("Chapters"); + + b.Navigation("MediaFiles"); + + b.Navigation("Streams"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Navigation("MultiCollectionItems"); + + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artists"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Navigation("Playlists"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Navigation("FillGroupIndices"); + + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("ProgramScheduleAlternates"); + + b.Navigation("ProgramScheduleAnchors"); + + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Navigation("Items"); + + b.Navigation("Playouts"); + + b.Navigation("ProgramScheduleAlternates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("TemplateItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Navigation("Blocks"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Navigation("Decos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Navigation("DecoTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Navigation("Guids"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.Navigation("ArtistMetadata"); + + b.Navigation("MusicVideos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.Navigation("EpisodeMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.Navigation("ImageMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MovieMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MusicVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("OtherVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.Navigation("Episodes"); + + b.Navigation("SeasonMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.Navigation("Seasons"); + + b.Navigation("ShowMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("SongMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.cs b/ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.cs new file mode 100644 index 00000000..c13d640c --- /dev/null +++ b/ErsatzTV.Infrastructure.MySql/Migrations/20240716155846_Add_Playout_OnDemandCheckpoint.cs @@ -0,0 +1,29 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ErsatzTV.Infrastructure.MySql.Migrations +{ + /// + public partial class Add_Playout_OnDemandCheckpoint : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "OnDemandCheckpoint", + table: "Playout", + type: "datetime(6)", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "OnDemandCheckpoint", + table: "Playout"); + } + } +} diff --git a/ErsatzTV.Infrastructure.MySql/Migrations/TvContextModelSnapshot.cs b/ErsatzTV.Infrastructure.MySql/Migrations/TvContextModelSnapshot.cs index 265bb332..fff4f4d6 100644 --- a/ErsatzTV.Infrastructure.MySql/Migrations/TvContextModelSnapshot.cs +++ b/ErsatzTV.Infrastructure.MySql/Migrations/TvContextModelSnapshot.cs @@ -17,7 +17,7 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.5") + .HasAnnotation("ProductVersion", "8.0.7") .HasAnnotation("Relational:MaxIdentifierLength", 64); MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); @@ -277,6 +277,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations b.Property("PreferredSubtitleLanguageCode") .HasColumnType("longtext"); + b.Property("ProgressMode") + .HasColumnType("int"); + b.Property("StreamingMode") .HasColumnType("int"); @@ -1699,6 +1702,9 @@ namespace ErsatzTV.Infrastructure.MySql.Migrations b.Property("ExternalJsonFile") .HasColumnType("longtext"); + b.Property("OnDemandCheckpoint") + .HasColumnType("datetime(6)"); + b.Property("ProgramScheduleId") .HasColumnType("int"); diff --git a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj index 54e23d83..5155d5ae 100644 --- a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj +++ b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj @@ -13,8 +13,8 @@ - - + + diff --git a/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.Designer.cs b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.Designer.cs new file mode 100644 index 00000000..a998600b --- /dev/null +++ b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.Designer.cs @@ -0,0 +1,5641 @@ +// +using System; +using ErsatzTV.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ErsatzTV.Infrastructure.Sqlite.Migrations +{ + [DbContext(typeof(TvContext))] + [Migration("20240716135729_Add_Channel_ProgressMode")] + partial class Add_Channel_ProgressMode + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.7"); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ArtworkId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Order") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("TEXT"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ArtworkId") + .IsUnique(); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Actor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("Biography") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Disambiguation") + .HasColumnType("TEXT"); + + b.Property("Formed") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistId"); + + b.ToTable("ArtistMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ArtworkKind") + .HasColumnType("INTEGER"); + + b.Property("BlurHash43") + .HasColumnType("TEXT"); + + b.Property("BlurHash54") + .HasColumnType("TEXT"); + + b.Property("BlurHash64") + .HasColumnType("TEXT"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SourcePath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ChannelId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Artwork", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Categories") + .HasColumnType("TEXT"); + + b.Property("FFmpegProfileId") + .HasColumnType("INTEGER"); + + b.Property("FallbackFillerId") + .HasColumnType("INTEGER"); + + b.Property("Group") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValue("ErsatzTV"); + + b.Property("MusicVideoCreditsMode") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoCreditsTemplate") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Number") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioTitle") + .HasColumnType("TEXT"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("TEXT"); + + b.Property("ProgressMode") + .HasColumnType("INTEGER"); + + b.Property("StreamingMode") + .HasColumnType("INTEGER"); + + b.Property("SubtitleMode") + .HasColumnType("INTEGER"); + + b.Property("UniqueId") + .HasColumnType("TEXT"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("FFmpegProfileId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("Number") + .IsUnique(); + + b.HasIndex("WatermarkId"); + + b.ToTable("Channel", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ChannelWatermark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DurationSeconds") + .HasColumnType("INTEGER"); + + b.Property("FrequencyMinutes") + .HasColumnType("INTEGER"); + + b.Property("HorizontalMarginPercent") + .HasColumnType("INTEGER"); + + b.Property("Image") + .HasColumnType("TEXT"); + + b.Property("ImageSource") + .HasColumnType("INTEGER"); + + b.Property("Location") + .HasColumnType("INTEGER"); + + b.Property("Mode") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Opacity") + .HasColumnType("INTEGER"); + + b.Property("PlaceWithinSourceContent") + .HasColumnType("INTEGER"); + + b.Property("Size") + .HasColumnType("INTEGER"); + + b.Property("VerticalMarginPercent") + .HasColumnType("INTEGER"); + + b.Property("WidthPercent") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ChannelWatermark", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("UseCustomPlaybackOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Collection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("CustomIndex") + .HasColumnType("INTEGER"); + + b.HasKey("CollectionId", "MediaItemId"); + + b.HasIndex("MediaItemId"); + + b.ToTable("CollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ConfigElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("ConfigElement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Director", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Address") + .HasColumnType("TEXT"); + + b.Property("EmbyMediaSourceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EmbyMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("EmbyPath") + .HasColumnType("TEXT"); + + b.Property("LocalPath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("EpisodeId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.ToTable("EpisodeMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowBFrames") + .HasColumnType("INTEGER"); + + b.Property("AudioBitrate") + .HasColumnType("INTEGER"); + + b.Property("AudioBufferSize") + .HasColumnType("INTEGER"); + + b.Property("AudioChannels") + .HasColumnType("INTEGER"); + + b.Property("AudioFormat") + .HasColumnType("INTEGER"); + + b.Property("AudioSampleRate") + .HasColumnType("INTEGER"); + + b.Property("BitDepth") + .HasColumnType("INTEGER"); + + b.Property("DeinterlaceVideo") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(true); + + b.Property("HardwareAcceleration") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("NormalizeFramerate") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("NormalizeLoudnessMode") + .HasColumnType("INTEGER"); + + b.Property("QsvExtraHardwareFrames") + .HasColumnType("INTEGER"); + + b.Property("ResolutionId") + .HasColumnType("INTEGER"); + + b.Property("ScalingBehavior") + .HasColumnType("INTEGER"); + + b.Property("ThreadCount") + .HasColumnType("INTEGER"); + + b.Property("VaapiDevice") + .HasColumnType("TEXT"); + + b.Property("VaapiDriver") + .HasColumnType("INTEGER"); + + b.Property("VideoBitrate") + .HasColumnType("INTEGER"); + + b.Property("VideoBufferSize") + .HasColumnType("INTEGER"); + + b.Property("VideoFormat") + .HasColumnType("INTEGER"); + + b.Property("VideoPreset") + .HasColumnType("TEXT"); + + b.Property("VideoProfile") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ResolutionId"); + + b.ToTable("FFmpegProfile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowWatermarks") + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.Property("Duration") + .HasColumnType("TEXT"); + + b.Property("FillerKind") + .HasColumnType("INTEGER"); + + b.Property("FillerMode") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("PadToNearestMinute") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("FillerPreset", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Genre"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DurationSeconds") + .HasColumnType("REAL"); + + b.Property("LibraryFolderId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId") + .IsUnique(); + + b.ToTable("ImageFolderDuration", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DurationSeconds") + .HasColumnType("REAL"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("ImageMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Address") + .HasColumnType("TEXT"); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("JellyfinPath") + .HasColumnType("TEXT"); + + b.Property("LocalPath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LanguageCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EnglishName") + .HasColumnType("TEXT"); + + b.Property("FrenchName") + .HasColumnType("TEXT"); + + b.Property("ThreeCode1") + .HasColumnType("TEXT"); + + b.Property("ThreeCode2") + .HasColumnType("TEXT"); + + b.Property("TwoCode") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LanguageCode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LastScan") + .HasColumnType("TEXT"); + + b.Property("MediaKind") + .HasColumnType("INTEGER"); + + b.Property("MediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MediaSourceId"); + + b.ToTable("Library", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("LibraryPathId") + .HasColumnType("INTEGER"); + + b.Property("ParentId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.HasIndex("ParentId"); + + b.ToTable("LibraryFolder", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LastScan") + .HasColumnType("TEXT"); + + b.Property("LibraryId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryId"); + + b.ToTable("LibraryPath", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChapterId") + .HasColumnType("INTEGER"); + + b.Property("EndTime") + .HasColumnType("TEXT"); + + b.Property("MediaVersionId") + .HasColumnType("INTEGER"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaChapter", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryFolderId") + .HasColumnType("INTEGER"); + + b.Property("MediaVersionId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId"); + + b.HasIndex("MediaVersionId"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("MediaFile", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryPathId") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.ToTable("MediaItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("MediaSource", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttachedPic") + .HasColumnType("INTEGER"); + + b.Property("BitsPerRawSample") + .HasColumnType("INTEGER"); + + b.Property("Channels") + .HasColumnType("INTEGER"); + + b.Property("Codec") + .HasColumnType("TEXT"); + + b.Property("ColorPrimaries") + .HasColumnType("TEXT"); + + b.Property("ColorRange") + .HasColumnType("TEXT"); + + b.Property("ColorSpace") + .HasColumnType("TEXT"); + + b.Property("ColorTransfer") + .HasColumnType("TEXT"); + + b.Property("Default") + .HasColumnType("INTEGER"); + + b.Property("FileName") + .HasColumnType("TEXT"); + + b.Property("Forced") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("MediaStreamKind") + .HasColumnType("INTEGER"); + + b.Property("MediaVersionId") + .HasColumnType("INTEGER"); + + b.Property("MimeType") + .HasColumnType("TEXT"); + + b.Property("PixelFormat") + .HasColumnType("TEXT"); + + b.Property("Profile") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaStream", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DisplayAspectRatio") + .HasColumnType("TEXT"); + + b.Property("Duration") + .HasColumnType("TEXT"); + + b.Property("EpisodeId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MovieId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoId") + .HasColumnType("INTEGER"); + + b.Property("RFrameRate") + .HasColumnType("TEXT"); + + b.Property("SampleAspectRatio") + .HasColumnType("TEXT"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("VideoScanKind") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.HasIndex("ImageId"); + + b.HasIndex("MovieId"); + + b.HasIndex("MusicVideoId"); + + b.HasIndex("OtherVideoId"); + + b.HasIndex("SongId"); + + b.ToTable("MediaVersion", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Guid") + .HasColumnType("TEXT"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("MetadataGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Mood"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentRating") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("MovieId") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MovieId"); + + b.ToTable("MovieMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("MultiCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("ScheduleAsGroup") + .HasColumnType("INTEGER"); + + b.HasKey("MultiCollectionId", "CollectionId"); + + b.HasIndex("CollectionId"); + + b.ToTable("MultiCollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("ScheduleAsGroup") + .HasColumnType("INTEGER"); + + b.HasKey("MultiCollectionId", "SmartCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("MultiCollectionSmartItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoMetadataId"); + + b.ToTable("MusicVideoArtist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Album") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoId") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Track") + .HasColumnType("INTEGER"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoId"); + + b.ToTable("MusicVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentRating") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("OtherVideoId") + .HasColumnType("INTEGER"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OtherVideoId"); + + b.ToTable("OtherVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("PlaylistGroupId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlaylistGroupId", "Name") + .IsUnique(); + + b.ToTable("Playlist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("PlaylistGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlayAll") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("PlaylistId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlaylistItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("DailyRebuildTime") + .HasColumnType("TEXT"); + + b.Property("DecoId") + .HasColumnType("INTEGER"); + + b.Property("ExternalJsonFile") + .HasColumnType("TEXT"); + + b.Property("ProgramScheduleId") + .HasColumnType("INTEGER"); + + b.Property("ProgramSchedulePlayoutType") + .HasColumnType("INTEGER"); + + b.Property("Seed") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("DecoId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("Playout", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockKey") + .HasColumnType("TEXT"); + + b.Property("ChapterTitle") + .HasColumnType("TEXT"); + + b.Property("CollectionEtag") + .HasColumnType("TEXT"); + + b.Property("CollectionKey") + .HasColumnType("TEXT"); + + b.Property("CustomTitle") + .HasColumnType("TEXT"); + + b.Property("DisableWatermarks") + .HasColumnType("INTEGER"); + + b.Property("FillerKind") + .HasColumnType("INTEGER"); + + b.Property("Finish") + .HasColumnType("TEXT"); + + b.Property("GuideFinish") + .HasColumnType("TEXT"); + + b.Property("GuideGroup") + .HasColumnType("INTEGER"); + + b.Property("GuideStart") + .HasColumnType("TEXT"); + + b.Property("InPoint") + .HasColumnType("TEXT"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("OutPoint") + .HasColumnType("TEXT"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioTitle") + .HasColumnType("TEXT"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("TEXT"); + + b.Property("Start") + .HasColumnType("TEXT"); + + b.Property("SubtitleMode") + .HasColumnType("INTEGER"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("PlayoutItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnchorDate") + .HasColumnType("TEXT"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("FakeCollectionKey") + .HasColumnType("TEXT"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaylistId") + .HasColumnType("INTEGER"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlayoutProgramScheduleAnchor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("ProgramScheduleItemId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleItemId"); + + b.ToTable("PlayoutScheduleItemFillGroupIndex", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("PlexMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("Uri") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LocalPath") + .HasColumnType("TEXT"); + + b.Property("PlexMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("PlexPath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("KeepMultiPartEpisodesTogether") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RandomStartPoint") + .HasColumnType("INTEGER"); + + b.Property("ShuffleScheduleItems") + .HasColumnType("INTEGER"); + + b.Property("TreatCollectionsAsShows") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ProgramSchedule", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DaysOfMonth") + .HasColumnType("TEXT"); + + b.Property("DaysOfWeek") + .HasColumnType("TEXT"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MonthsOfYear") + .HasColumnType("TEXT"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("ProgramScheduleId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("ProgramScheduleAlternate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("CustomTitle") + .HasColumnType("TEXT"); + + b.Property("FakeCollectionKey") + .HasColumnType("TEXT"); + + b.Property("FallbackFillerId") + .HasColumnType("INTEGER"); + + b.Property("FillWithGroupMode") + .HasColumnType("INTEGER"); + + b.Property("GuideMode") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MidRollFillerId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("PlaylistId") + .HasColumnType("INTEGER"); + + b.Property("PostRollFillerId") + .HasColumnType("INTEGER"); + + b.Property("PreRollFillerId") + .HasColumnType("INTEGER"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioTitle") + .HasColumnType("TEXT"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("TEXT"); + + b.Property("ProgramScheduleId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.Property("SubtitleMode") + .HasColumnType("INTEGER"); + + b.Property("TailFillerId") + .HasColumnType("INTEGER"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MidRollFillerId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PostRollFillerId"); + + b.HasIndex("PreRollFillerId"); + + b.HasIndex("ProgramScheduleId"); + + b.HasIndex("SmartCollectionId"); + + b.HasIndex("TailFillerId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("ProgramScheduleItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Resolution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("IsCustom") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Resolution", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockGroupId") + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Minutes") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("StopScheduling") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BlockGroupId", "Name") + .IsUnique(); + + b.ToTable("Block", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("BlockGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockId") + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("BlockItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackCollectionId") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackCollectionType") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackMediaItemId") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackMode") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackMultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackSmartCollectionId") + .HasColumnType("INTEGER"); + + b.Property("DecoGroupId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.Property("WatermarkMode") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DeadAirFallbackCollectionId"); + + b.HasIndex("DeadAirFallbackMediaItemId"); + + b.HasIndex("DeadAirFallbackMultiCollectionId"); + + b.HasIndex("DeadAirFallbackSmartCollectionId"); + + b.HasIndex("WatermarkId"); + + b.HasIndex("DecoGroupId", "Name") + .IsUnique(); + + b.ToTable("Deco", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DecoTemplateGroupId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateGroupId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DecoId") + .HasColumnType("INTEGER"); + + b.Property("DecoTemplateId") + .HasColumnType("INTEGER"); + + b.Property("EndTime") + .HasColumnType("TEXT"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DecoId"); + + b.HasIndex("DecoTemplateId"); + + b.ToTable("DecoTemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockId") + .HasColumnType("INTEGER"); + + b.Property("Details") + .HasColumnType("TEXT"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("PlayoutId"); + + b.ToTable("PlayoutHistory", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DaysOfMonth") + .HasColumnType("TEXT"); + + b.Property("DaysOfWeek") + .HasColumnType("TEXT"); + + b.Property("DecoTemplateId") + .HasColumnType("INTEGER"); + + b.Property("EndDay") + .HasColumnType("INTEGER"); + + b.Property("EndMonth") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("LimitToDateRange") + .HasColumnType("INTEGER"); + + b.Property("MonthsOfYear") + .HasColumnType("TEXT"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("StartDay") + .HasColumnType("INTEGER"); + + b.Property("StartMonth") + .HasColumnType("INTEGER"); + + b.Property("TemplateId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("TemplateId"); + + b.ToTable("PlayoutTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("TemplateGroupId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("TemplateGroupId"); + + b.ToTable("Template", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("TemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockId") + .HasColumnType("INTEGER"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.Property("TemplateId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("TemplateId"); + + b.ToTable("TemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("SeasonMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentRating") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("ShowId") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ShowId"); + + b.ToTable("ShowMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Query") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SmartCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Album") + .HasColumnType("TEXT"); + + b.Property("AlbumArtists") + .HasColumnType("TEXT"); + + b.Property("Artists") + .HasColumnType("TEXT"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Track") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SongId"); + + b.ToTable("SongMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Studio", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Style"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Codec") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Default") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Forced") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("IsExtracted") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("SDH") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.Property("StreamIndex") + .HasColumnType("INTEGER"); + + b.Property("SubtitleKind") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Subtitle", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ExternalCollectionId") + .HasColumnType("TEXT"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Tag"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("ItemCount") + .HasColumnType("INTEGER"); + + b.Property("List") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("TraktId") + .HasColumnType("INTEGER"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("TraktList", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Episode") + .HasColumnType("INTEGER"); + + b.Property("Kind") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Season") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TraktId") + .HasColumnType("INTEGER"); + + b.Property("TraktListId") + .HasColumnType("INTEGER"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("TraktListId"); + + b.ToTable("TraktListItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Guid") + .HasColumnType("TEXT"); + + b.Property("TraktListItemId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("TraktListItemId"); + + b.ToTable("TraktListItemGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Writer", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EmbyLibraryId") + .HasColumnType("INTEGER"); + + b.Property("NetworkPath") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EmbyLibraryId"); + + b.ToTable("EmbyPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JellyfinLibraryId") + .HasColumnType("INTEGER"); + + b.Property("NetworkPath") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinLibraryId"); + + b.ToTable("JellyfinPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("ShouldSyncItems") + .HasColumnType("INTEGER"); + + b.ToTable("EmbyLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("ShouldSyncItems") + .HasColumnType("INTEGER"); + + b.ToTable("JellyfinLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.ToTable("LocalLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("ShouldSyncItems") + .HasColumnType("INTEGER"); + + b.ToTable("PlexLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaFile"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("PlexId") + .HasColumnType("INTEGER"); + + b.ToTable("PlexMediaFile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Artist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.HasIndex("SeasonId"); + + b.ToTable("Episode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Image", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Movie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.HasIndex("ArtistId"); + + b.ToTable("MusicVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("OtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("ShowId") + .HasColumnType("INTEGER"); + + b.HasIndex("ShowId"); + + b.ToTable("Season", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Show", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Song", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("TEXT"); + + b.Property("OperatingSystem") + .HasColumnType("TEXT"); + + b.Property("ServerName") + .HasColumnType("TEXT"); + + b.ToTable("EmbyMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("TEXT"); + + b.Property("OperatingSystem") + .HasColumnType("TEXT"); + + b.Property("ServerName") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.ToTable("LocalMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("ClientIdentifier") + .HasColumnType("TEXT"); + + b.Property("LastCollectionsScan") + .HasColumnType("TEXT"); + + b.Property("Platform") + .HasColumnType("TEXT"); + + b.Property("PlatformVersion") + .HasColumnType("TEXT"); + + b.Property("ProductVersion") + .HasColumnType("TEXT"); + + b.Property("ServerName") + .HasColumnType("TEXT"); + + b.ToTable("PlexMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("DiscardToFillAttempts") + .HasColumnType("INTEGER"); + + b.Property("PlayoutDuration") + .HasColumnType("TEXT"); + + b.Property("TailMode") + .HasColumnType("INTEGER"); + + b.ToTable("ProgramScheduleDurationItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleFloodItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.ToTable("ProgramScheduleMultipleItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleOneItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbyEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbyMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.OtherVideo"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexOtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbySeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbyShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Actors") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Artwork", "Artwork") + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Actor", "ArtworkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Actors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Actors") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Actors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Actors") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Actors") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Actors") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Artwork"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("ArtistMetadata") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Channel", null) + .WithMany("Artwork") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Artwork") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.HasOne("ErsatzTV.Core.Domain.FFmpegProfile", "FFmpegProfile") + .WithMany() + .HasForeignKey("FFmpegProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("FFmpegProfile"); + + b.Navigation("FallbackFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("CollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("CollectionItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Directors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Directors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("Connections") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", "Episode") + .WithMany("EpisodeMetadata") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Episode"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.HasOne("ErsatzTV.Core.Domain.Resolution", "Resolution") + .WithMany() + .HasForeignKey("ResolutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Resolution"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Genres") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Genres") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Genres") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Genres") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Genres") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Genres") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Genres") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithOne("ImageFolderDuration") + .HasForeignKey("ErsatzTV.Core.Domain.ImageFolderDuration", "LibraryFolderId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("LibraryFolder"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Image", "Image") + .WithMany("ImageMetadata") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("Connections") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", "MediaSource") + .WithMany("Libraries") + .HasForeignKey("MediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("LibraryFolders") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("LibraryPath"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", "Library") + .WithMany("Paths") + .HasForeignKey("LibraryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Library"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Chapters") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithMany("MediaFiles") + .HasForeignKey("LibraryFolderId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("MediaFiles") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryFolder"); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("MediaItems") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryPath"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Streams") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithMany("MediaVersions") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Image", null) + .WithMany("MediaVersions") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithMany("MediaVersions") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Song", null) + .WithMany("MediaVersions") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Guids") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Guids") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Guids") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Guids") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Guids") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Guids") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Guids") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Moods") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", "Movie") + .WithMany("MovieMetadata") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Movie"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("MultiCollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MultiCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artists") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", "MusicVideo") + .WithMany("MusicVideoMetadata") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MusicVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", "OtherVideo") + .WithMany("OtherVideoMetadata") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OtherVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlaylistGroup", "PlaylistGroup") + .WithMany("Playlists") + .HasForeignKey("PlaylistGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlaylistGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany("Items") + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.HasOne("ErsatzTV.Core.Domain.Channel", "Channel") + .WithMany("Playouts") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany("Playouts") + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Playouts") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 => + { + b1.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b1.Property("DurationFinish") + .HasColumnType("TEXT"); + + b1.Property("InDurationFiller") + .HasColumnType("INTEGER"); + + b1.Property("InFlood") + .HasColumnType("INTEGER"); + + b1.Property("MultipleRemaining") + .HasColumnType("INTEGER"); + + b1.Property("NextGuideGroup") + .HasColumnType("INTEGER"); + + b1.Property("NextStart") + .HasColumnType("TEXT"); + + b1.HasKey("PlayoutId"); + + b1.ToTable("PlayoutAnchor", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutId"); + + b1.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "ScheduleItemsEnumeratorState", b2 => + { + b2.Property("PlayoutAnchorPlayoutId") + .HasColumnType("INTEGER"); + + b2.Property("Index") + .HasColumnType("INTEGER"); + + b2.Property("Seed") + .HasColumnType("INTEGER"); + + b2.HasKey("PlayoutAnchorPlayoutId"); + + b2.ToTable("ScheduleItemsEnumeratorState", (string)null); + + b2.WithOwner() + .HasForeignKey("PlayoutAnchorPlayoutId"); + }); + + b1.Navigation("ScheduleItemsEnumeratorState"); + }); + + b.Navigation("Anchor"); + + b.Navigation("Channel"); + + b.Navigation("Deco"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Items") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("MediaItem"); + + b.Navigation("Playout"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAnchors") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutProgramScheduleAnchorId") + .HasColumnType("INTEGER"); + + b1.Property("Index") + .HasColumnType("INTEGER"); + + b1.Property("Seed") + .HasColumnType("INTEGER"); + + b1.HasKey("PlayoutProgramScheduleAnchorId"); + + b1.ToTable("CollectionEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutProgramScheduleAnchorId"); + }); + + b.Navigation("Collection"); + + b.Navigation("EnumeratorState"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("Playout"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("FillGroupIndices") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", "ProgramScheduleItem") + .WithMany() + .HasForeignKey("ProgramScheduleItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutScheduleItemFillGroupIndexId") + .HasColumnType("INTEGER"); + + b1.Property("Index") + .HasColumnType("INTEGER"); + + b1.Property("Seed") + .HasColumnType("INTEGER"); + + b1.HasKey("PlayoutScheduleItemFillGroupIndexId"); + + b1.ToTable("FillGroupEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutScheduleItemFillGroupIndexId"); + }); + + b.Navigation("EnumeratorState"); + + b.Navigation("Playout"); + + b.Navigation("ProgramScheduleItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("Connections") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Playout"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "MidRollFiller") + .WithMany() + .HasForeignKey("MidRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PostRollFiller") + .WithMany() + .HasForeignKey("PostRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PreRollFiller") + .WithMany() + .HasForeignKey("PreRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Items") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "TailFiller") + .WithMany() + .HasForeignKey("TailFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Collection"); + + b.Navigation("FallbackFiller"); + + b.Navigation("MediaItem"); + + b.Navigation("MidRollFiller"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("PostRollFiller"); + + b.Navigation("PreRollFiller"); + + b.Navigation("ProgramSchedule"); + + b.Navigation("SmartCollection"); + + b.Navigation("TailFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.BlockGroup", "BlockGroup") + .WithMany("Blocks") + .HasForeignKey("BlockGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BlockGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("Items") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Block"); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "DeadAirFallbackCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "DeadAirFallbackMediaItem") + .WithMany() + .HasForeignKey("DeadAirFallbackMediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "DeadAirFallbackMultiCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackMultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "DeadAirFallbackSmartCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackSmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoGroup", "DecoGroup") + .WithMany("Decos") + .HasForeignKey("DecoGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("DeadAirFallbackCollection"); + + b.Navigation("DeadAirFallbackMediaItem"); + + b.Navigation("DeadAirFallbackMultiCollection"); + + b.Navigation("DeadAirFallbackSmartCollection"); + + b.Navigation("DecoGroup"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", "DecoTemplateGroup") + .WithMany("DecoTemplates") + .HasForeignKey("DecoTemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany() + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("Items") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Deco"); + + b.Navigation("DecoTemplate"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("PlayoutHistory") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("PlayoutHistory") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Playout"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("PlayoutTemplates") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Templates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("PlayoutTemplates") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplate"); + + b.Navigation("Playout"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", "TemplateGroup") + .WithMany("Templates") + .HasForeignKey("TemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("TemplateItems") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("Items") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("SeasonMetadata") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("ShowMetadata") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Song", "Song") + .WithMany("SongMetadata") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Song"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Studios") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Studios") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Studios") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Studios") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Studios") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Studios") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Studios") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Styles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Tags") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Tags") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Tags") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Tags") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Tags") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Tags") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Tags") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("TraktListItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.TraktList", "TraktList") + .WithMany("Items") + .HasForeignKey("TraktListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("TraktList"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.TraktListItem", "TraktListItem") + .WithMany("Guids") + .HasForeignKey("TraktListItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TraktListItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Writers") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Writers") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Writers") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("EmbyLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("JellyfinLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaFile", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaFile", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Artist", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Episode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Image", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Movie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("MusicVideos") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.MusicVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.OtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Season", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("Seasons") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Show", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Song", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemOne", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexOtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbySeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Moods"); + + b.Navigation("Studios"); + + b.Navigation("Styles"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Navigation("Artwork"); + + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("MultiCollectionItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Navigation("Paths"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Navigation("Children"); + + b.Navigation("ImageFolderDuration"); + + b.Navigation("MediaFiles"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Navigation("LibraryFolders"); + + b.Navigation("MediaItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("TraktListItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Navigation("Libraries"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Navigation("Chapters"); + + b.Navigation("MediaFiles"); + + b.Navigation("Streams"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Navigation("MultiCollectionItems"); + + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artists"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Navigation("Playlists"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Navigation("FillGroupIndices"); + + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("ProgramScheduleAlternates"); + + b.Navigation("ProgramScheduleAnchors"); + + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Navigation("Items"); + + b.Navigation("Playouts"); + + b.Navigation("ProgramScheduleAlternates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("TemplateItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Navigation("Blocks"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Navigation("Decos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Navigation("DecoTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Navigation("Guids"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.Navigation("ArtistMetadata"); + + b.Navigation("MusicVideos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.Navigation("EpisodeMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.Navigation("ImageMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MovieMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MusicVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("OtherVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.Navigation("Episodes"); + + b.Navigation("SeasonMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.Navigation("Seasons"); + + b.Navigation("ShowMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("SongMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.cs b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.cs new file mode 100644 index 00000000..ff280c91 --- /dev/null +++ b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716135729_Add_Channel_ProgressMode.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ErsatzTV.Infrastructure.Sqlite.Migrations +{ + /// + public partial class Add_Channel_ProgressMode : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ProgressMode", + table: "Channel", + type: "INTEGER", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ProgressMode", + table: "Channel"); + } + } +} diff --git a/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.Designer.cs b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.Designer.cs new file mode 100644 index 00000000..d15eb92c --- /dev/null +++ b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.Designer.cs @@ -0,0 +1,5644 @@ +// +using System; +using ErsatzTV.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace ErsatzTV.Infrastructure.Sqlite.Migrations +{ + [DbContext(typeof(TvContext))] + [Migration("20240716150019_Add_Playout_OnDemandCheckpoint")] + partial class Add_Playout_OnDemandCheckpoint + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.7"); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ArtworkId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Order") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Role") + .HasColumnType("TEXT"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ArtworkId") + .IsUnique(); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Actor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("Biography") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Disambiguation") + .HasColumnType("TEXT"); + + b.Property("Formed") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistId"); + + b.ToTable("ArtistMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ArtworkKind") + .HasColumnType("INTEGER"); + + b.Property("BlurHash43") + .HasColumnType("TEXT"); + + b.Property("BlurHash54") + .HasColumnType("TEXT"); + + b.Property("BlurHash64") + .HasColumnType("TEXT"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SourcePath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("ChannelId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Artwork", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Categories") + .HasColumnType("TEXT"); + + b.Property("FFmpegProfileId") + .HasColumnType("INTEGER"); + + b.Property("FallbackFillerId") + .HasColumnType("INTEGER"); + + b.Property("Group") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("TEXT") + .HasDefaultValue("ErsatzTV"); + + b.Property("MusicVideoCreditsMode") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoCreditsTemplate") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Number") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioTitle") + .HasColumnType("TEXT"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("TEXT"); + + b.Property("ProgressMode") + .HasColumnType("INTEGER"); + + b.Property("StreamingMode") + .HasColumnType("INTEGER"); + + b.Property("SubtitleMode") + .HasColumnType("INTEGER"); + + b.Property("UniqueId") + .HasColumnType("TEXT"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("FFmpegProfileId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("Number") + .IsUnique(); + + b.HasIndex("WatermarkId"); + + b.ToTable("Channel", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ChannelWatermark", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DurationSeconds") + .HasColumnType("INTEGER"); + + b.Property("FrequencyMinutes") + .HasColumnType("INTEGER"); + + b.Property("HorizontalMarginPercent") + .HasColumnType("INTEGER"); + + b.Property("Image") + .HasColumnType("TEXT"); + + b.Property("ImageSource") + .HasColumnType("INTEGER"); + + b.Property("Location") + .HasColumnType("INTEGER"); + + b.Property("Mode") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Opacity") + .HasColumnType("INTEGER"); + + b.Property("PlaceWithinSourceContent") + .HasColumnType("INTEGER"); + + b.Property("Size") + .HasColumnType("INTEGER"); + + b.Property("VerticalMarginPercent") + .HasColumnType("INTEGER"); + + b.Property("WidthPercent") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ChannelWatermark", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("UseCustomPlaybackOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Collection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("CustomIndex") + .HasColumnType("INTEGER"); + + b.HasKey("CollectionId", "MediaItemId"); + + b.HasIndex("MediaItemId"); + + b.ToTable("CollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ConfigElement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key") + .IsUnique(); + + b.ToTable("ConfigElement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Director", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Address") + .HasColumnType("TEXT"); + + b.Property("EmbyMediaSourceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EmbyMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("EmbyPath") + .HasColumnType("TEXT"); + + b.Property("LocalPath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EmbyMediaSourceId"); + + b.ToTable("EmbyPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("EpisodeId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.ToTable("EpisodeMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowBFrames") + .HasColumnType("INTEGER"); + + b.Property("AudioBitrate") + .HasColumnType("INTEGER"); + + b.Property("AudioBufferSize") + .HasColumnType("INTEGER"); + + b.Property("AudioChannels") + .HasColumnType("INTEGER"); + + b.Property("AudioFormat") + .HasColumnType("INTEGER"); + + b.Property("AudioSampleRate") + .HasColumnType("INTEGER"); + + b.Property("BitDepth") + .HasColumnType("INTEGER"); + + b.Property("DeinterlaceVideo") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(true); + + b.Property("HardwareAcceleration") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("NormalizeFramerate") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("NormalizeLoudnessMode") + .HasColumnType("INTEGER"); + + b.Property("QsvExtraHardwareFrames") + .HasColumnType("INTEGER"); + + b.Property("ResolutionId") + .HasColumnType("INTEGER"); + + b.Property("ScalingBehavior") + .HasColumnType("INTEGER"); + + b.Property("ThreadCount") + .HasColumnType("INTEGER"); + + b.Property("VaapiDevice") + .HasColumnType("TEXT"); + + b.Property("VaapiDriver") + .HasColumnType("INTEGER"); + + b.Property("VideoBitrate") + .HasColumnType("INTEGER"); + + b.Property("VideoBufferSize") + .HasColumnType("INTEGER"); + + b.Property("VideoFormat") + .HasColumnType("INTEGER"); + + b.Property("VideoPreset") + .HasColumnType("TEXT"); + + b.Property("VideoProfile") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ResolutionId"); + + b.ToTable("FFmpegProfile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowWatermarks") + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.Property("Duration") + .HasColumnType("TEXT"); + + b.Property("FillerKind") + .HasColumnType("INTEGER"); + + b.Property("FillerMode") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("PadToNearestMinute") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("FillerPreset", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Genre"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DurationSeconds") + .HasColumnType("REAL"); + + b.Property("LibraryFolderId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId") + .IsUnique(); + + b.ToTable("ImageFolderDuration", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DurationSeconds") + .HasColumnType("REAL"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("ImageMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Address") + .HasColumnType("TEXT"); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JellyfinMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("JellyfinPath") + .HasColumnType("TEXT"); + + b.Property("LocalPath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinMediaSourceId"); + + b.ToTable("JellyfinPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LanguageCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EnglishName") + .HasColumnType("TEXT"); + + b.Property("FrenchName") + .HasColumnType("TEXT"); + + b.Property("ThreeCode1") + .HasColumnType("TEXT"); + + b.Property("ThreeCode2") + .HasColumnType("TEXT"); + + b.Property("TwoCode") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("LanguageCode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LastScan") + .HasColumnType("TEXT"); + + b.Property("MediaKind") + .HasColumnType("INTEGER"); + + b.Property("MediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MediaSourceId"); + + b.ToTable("Library", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("LibraryPathId") + .HasColumnType("INTEGER"); + + b.Property("ParentId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.HasIndex("ParentId"); + + b.ToTable("LibraryFolder", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LastScan") + .HasColumnType("TEXT"); + + b.Property("LibraryId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryId"); + + b.ToTable("LibraryPath", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChapterId") + .HasColumnType("INTEGER"); + + b.Property("EndTime") + .HasColumnType("TEXT"); + + b.Property("MediaVersionId") + .HasColumnType("INTEGER"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaChapter", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryFolderId") + .HasColumnType("INTEGER"); + + b.Property("MediaVersionId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LibraryFolderId"); + + b.HasIndex("MediaVersionId"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("MediaFile", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LibraryPathId") + .HasColumnType("INTEGER"); + + b.Property("State") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("LibraryPathId"); + + b.ToTable("MediaItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("MediaSource", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttachedPic") + .HasColumnType("INTEGER"); + + b.Property("BitsPerRawSample") + .HasColumnType("INTEGER"); + + b.Property("Channels") + .HasColumnType("INTEGER"); + + b.Property("Codec") + .HasColumnType("TEXT"); + + b.Property("ColorPrimaries") + .HasColumnType("TEXT"); + + b.Property("ColorRange") + .HasColumnType("TEXT"); + + b.Property("ColorSpace") + .HasColumnType("TEXT"); + + b.Property("ColorTransfer") + .HasColumnType("TEXT"); + + b.Property("Default") + .HasColumnType("INTEGER"); + + b.Property("FileName") + .HasColumnType("TEXT"); + + b.Property("Forced") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("MediaStreamKind") + .HasColumnType("INTEGER"); + + b.Property("MediaVersionId") + .HasColumnType("INTEGER"); + + b.Property("MimeType") + .HasColumnType("TEXT"); + + b.Property("PixelFormat") + .HasColumnType("TEXT"); + + b.Property("Profile") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MediaVersionId"); + + b.ToTable("MediaStream", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DisplayAspectRatio") + .HasColumnType("TEXT"); + + b.Property("Duration") + .HasColumnType("TEXT"); + + b.Property("EpisodeId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MovieId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoId") + .HasColumnType("INTEGER"); + + b.Property("RFrameRate") + .HasColumnType("TEXT"); + + b.Property("SampleAspectRatio") + .HasColumnType("TEXT"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("VideoScanKind") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeId"); + + b.HasIndex("ImageId"); + + b.HasIndex("MovieId"); + + b.HasIndex("MusicVideoId"); + + b.HasIndex("OtherVideoId"); + + b.HasIndex("SongId"); + + b.ToTable("MediaVersion", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Guid") + .HasColumnType("TEXT"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("MetadataGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Mood"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentRating") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("MovieId") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MovieId"); + + b.ToTable("MovieMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("MultiCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("ScheduleAsGroup") + .HasColumnType("INTEGER"); + + b.HasKey("MultiCollectionId", "CollectionId"); + + b.HasIndex("CollectionId"); + + b.ToTable("MultiCollectionItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("ScheduleAsGroup") + .HasColumnType("INTEGER"); + + b.HasKey("MultiCollectionId", "SmartCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("MultiCollectionSmartItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoMetadataId"); + + b.ToTable("MusicVideoArtist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Album") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoId") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Track") + .HasColumnType("INTEGER"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MusicVideoId"); + + b.ToTable("MusicVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentRating") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("OtherVideoId") + .HasColumnType("INTEGER"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OtherVideoId"); + + b.ToTable("OtherVideoMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("PlaylistGroupId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlaylistGroupId", "Name") + .IsUnique(); + + b.ToTable("Playlist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("PlaylistGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlayAll") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("PlaylistId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlaylistItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChannelId") + .HasColumnType("INTEGER"); + + b.Property("DailyRebuildTime") + .HasColumnType("TEXT"); + + b.Property("DecoId") + .HasColumnType("INTEGER"); + + b.Property("ExternalJsonFile") + .HasColumnType("TEXT"); + + b.Property("OnDemandCheckpoint") + .HasColumnType("TEXT"); + + b.Property("ProgramScheduleId") + .HasColumnType("INTEGER"); + + b.Property("ProgramSchedulePlayoutType") + .HasColumnType("INTEGER"); + + b.Property("Seed") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("DecoId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("Playout", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockKey") + .HasColumnType("TEXT"); + + b.Property("ChapterTitle") + .HasColumnType("TEXT"); + + b.Property("CollectionEtag") + .HasColumnType("TEXT"); + + b.Property("CollectionKey") + .HasColumnType("TEXT"); + + b.Property("CustomTitle") + .HasColumnType("TEXT"); + + b.Property("DisableWatermarks") + .HasColumnType("INTEGER"); + + b.Property("FillerKind") + .HasColumnType("INTEGER"); + + b.Property("Finish") + .HasColumnType("TEXT"); + + b.Property("GuideFinish") + .HasColumnType("TEXT"); + + b.Property("GuideGroup") + .HasColumnType("INTEGER"); + + b.Property("GuideStart") + .HasColumnType("TEXT"); + + b.Property("InPoint") + .HasColumnType("TEXT"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("OutPoint") + .HasColumnType("TEXT"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioTitle") + .HasColumnType("TEXT"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("TEXT"); + + b.Property("Start") + .HasColumnType("TEXT"); + + b.Property("SubtitleMode") + .HasColumnType("INTEGER"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("PlayoutItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AnchorDate") + .HasColumnType("TEXT"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("FakeCollectionKey") + .HasColumnType("TEXT"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaylistId") + .HasColumnType("INTEGER"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("PlayoutProgramScheduleAnchor", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("ProgramScheduleItemId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleItemId"); + + b.ToTable("PlayoutScheduleItemFillGroupIndex", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("PlexMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("Uri") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexConnection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("LocalPath") + .HasColumnType("TEXT"); + + b.Property("PlexMediaSourceId") + .HasColumnType("INTEGER"); + + b.Property("PlexPath") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PlexMediaSourceId"); + + b.ToTable("PlexPathReplacement", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("KeepMultiPartEpisodesTogether") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("RandomStartPoint") + .HasColumnType("INTEGER"); + + b.Property("ShuffleScheduleItems") + .HasColumnType("INTEGER"); + + b.Property("TreatCollectionsAsShows") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ProgramSchedule", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DaysOfMonth") + .HasColumnType("TEXT"); + + b.Property("DaysOfWeek") + .HasColumnType("TEXT"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MonthsOfYear") + .HasColumnType("TEXT"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("ProgramScheduleId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("ProgramScheduleId"); + + b.ToTable("ProgramScheduleAlternate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("CustomTitle") + .HasColumnType("TEXT"); + + b.Property("FakeCollectionKey") + .HasColumnType("TEXT"); + + b.Property("FallbackFillerId") + .HasColumnType("INTEGER"); + + b.Property("FillWithGroupMode") + .HasColumnType("INTEGER"); + + b.Property("GuideMode") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MidRollFillerId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("PlaylistId") + .HasColumnType("INTEGER"); + + b.Property("PostRollFillerId") + .HasColumnType("INTEGER"); + + b.Property("PreRollFillerId") + .HasColumnType("INTEGER"); + + b.Property("PreferredAudioLanguageCode") + .HasColumnType("TEXT"); + + b.Property("PreferredAudioTitle") + .HasColumnType("TEXT"); + + b.Property("PreferredSubtitleLanguageCode") + .HasColumnType("TEXT"); + + b.Property("ProgramScheduleId") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.Property("SubtitleMode") + .HasColumnType("INTEGER"); + + b.Property("TailFillerId") + .HasColumnType("INTEGER"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CollectionId"); + + b.HasIndex("FallbackFillerId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MidRollFillerId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("PlaylistId"); + + b.HasIndex("PostRollFillerId"); + + b.HasIndex("PreRollFillerId"); + + b.HasIndex("ProgramScheduleId"); + + b.HasIndex("SmartCollectionId"); + + b.HasIndex("TailFillerId"); + + b.HasIndex("WatermarkId"); + + b.ToTable("ProgramScheduleItem", (string)null); + + b.UseTptMappingStrategy(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Resolution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("IsCustom") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Resolution", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockGroupId") + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Minutes") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("StopScheduling") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BlockGroupId", "Name") + .IsUnique(); + + b.ToTable("Block", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("BlockGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockId") + .HasColumnType("INTEGER"); + + b.Property("CollectionId") + .HasColumnType("INTEGER"); + + b.Property("CollectionType") + .HasColumnType("INTEGER"); + + b.Property("IncludeInProgramGuide") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("MultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("SmartCollectionId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("CollectionId"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("MultiCollectionId"); + + b.HasIndex("SmartCollectionId"); + + b.ToTable("BlockItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackCollectionId") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackCollectionType") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackMediaItemId") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackMode") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackMultiCollectionId") + .HasColumnType("INTEGER"); + + b.Property("DeadAirFallbackSmartCollectionId") + .HasColumnType("INTEGER"); + + b.Property("DecoGroupId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("WatermarkId") + .HasColumnType("INTEGER"); + + b.Property("WatermarkMode") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DeadAirFallbackCollectionId"); + + b.HasIndex("DeadAirFallbackMediaItemId"); + + b.HasIndex("DeadAirFallbackMultiCollectionId"); + + b.HasIndex("DeadAirFallbackSmartCollectionId"); + + b.HasIndex("WatermarkId"); + + b.HasIndex("DecoGroupId", "Name") + .IsUnique(); + + b.ToTable("Deco", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DecoTemplateGroupId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateGroupId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("DecoTemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DecoId") + .HasColumnType("INTEGER"); + + b.Property("DecoTemplateId") + .HasColumnType("INTEGER"); + + b.Property("EndTime") + .HasColumnType("TEXT"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DecoId"); + + b.HasIndex("DecoTemplateId"); + + b.ToTable("DecoTemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockId") + .HasColumnType("INTEGER"); + + b.Property("Details") + .HasColumnType("TEXT"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("PlaybackOrder") + .HasColumnType("INTEGER"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("When") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("PlayoutId"); + + b.ToTable("PlayoutHistory", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("DaysOfMonth") + .HasColumnType("TEXT"); + + b.Property("DaysOfWeek") + .HasColumnType("TEXT"); + + b.Property("DecoTemplateId") + .HasColumnType("INTEGER"); + + b.Property("EndDay") + .HasColumnType("INTEGER"); + + b.Property("EndMonth") + .HasColumnType("INTEGER"); + + b.Property("Index") + .HasColumnType("INTEGER"); + + b.Property("LimitToDateRange") + .HasColumnType("INTEGER"); + + b.Property("MonthsOfYear") + .HasColumnType("TEXT"); + + b.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b.Property("StartDay") + .HasColumnType("INTEGER"); + + b.Property("StartMonth") + .HasColumnType("INTEGER"); + + b.Property("TemplateId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("DecoTemplateId"); + + b.HasIndex("PlayoutId"); + + b.HasIndex("TemplateId"); + + b.ToTable("PlayoutTemplate", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("TemplateGroupId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.HasIndex("TemplateGroupId"); + + b.ToTable("Template", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("TemplateGroup", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BlockId") + .HasColumnType("INTEGER"); + + b.Property("StartTime") + .HasColumnType("TEXT"); + + b.Property("TemplateId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("BlockId"); + + b.HasIndex("TemplateId"); + + b.ToTable("TemplateItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("SeasonMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ContentRating") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("Outline") + .HasColumnType("TEXT"); + + b.Property("Plot") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("ShowId") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Tagline") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ShowId"); + + b.ToTable("ShowMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Query") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SmartCollection", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Album") + .HasColumnType("TEXT"); + + b.Property("AlbumArtists") + .HasColumnType("TEXT"); + + b.Property("Artists") + .HasColumnType("TEXT"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("MetadataKind") + .HasColumnType("INTEGER"); + + b.Property("OriginalTitle") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("SongId") + .HasColumnType("INTEGER"); + + b.Property("SortTitle") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Track") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SongId"); + + b.ToTable("SongMetadata", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Studio", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.ToTable("Style"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Codec") + .HasColumnType("TEXT"); + + b.Property("DateAdded") + .HasColumnType("TEXT"); + + b.Property("DateUpdated") + .HasColumnType("TEXT"); + + b.Property("Default") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Forced") + .HasColumnType("INTEGER"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("IsExtracted") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.Property("SDH") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER") + .HasDefaultValue(false); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.Property("StreamIndex") + .HasColumnType("INTEGER"); + + b.Property("SubtitleKind") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Subtitle", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistMetadataId") + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ExternalCollectionId") + .HasColumnType("TEXT"); + + b.Property("ImageMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MusicVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SeasonMetadataId") + .HasColumnType("INTEGER"); + + b.Property("ShowMetadataId") + .HasColumnType("INTEGER"); + + b.Property("SongMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ArtistMetadataId"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("ImageMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("MusicVideoMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.HasIndex("SeasonMetadataId"); + + b.HasIndex("ShowMetadataId"); + + b.HasIndex("SongMetadataId"); + + b.ToTable("Tag"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("ItemCount") + .HasColumnType("INTEGER"); + + b.Property("List") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("TraktId") + .HasColumnType("INTEGER"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("TraktList", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Episode") + .HasColumnType("INTEGER"); + + b.Property("Kind") + .HasColumnType("INTEGER"); + + b.Property("MediaItemId") + .HasColumnType("INTEGER"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Season") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TraktId") + .HasColumnType("INTEGER"); + + b.Property("TraktListId") + .HasColumnType("INTEGER"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("MediaItemId"); + + b.HasIndex("TraktListId"); + + b.ToTable("TraktListItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Guid") + .HasColumnType("TEXT"); + + b.Property("TraktListItemId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("TraktListItemId"); + + b.ToTable("TraktListItemGuid", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeMetadataId") + .HasColumnType("INTEGER"); + + b.Property("MovieMetadataId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("OtherVideoMetadataId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("EpisodeMetadataId"); + + b.HasIndex("MovieMetadataId"); + + b.HasIndex("OtherVideoMetadataId"); + + b.ToTable("Writer", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EmbyLibraryId") + .HasColumnType("INTEGER"); + + b.Property("NetworkPath") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EmbyLibraryId"); + + b.ToTable("EmbyPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("JellyfinLibraryId") + .HasColumnType("INTEGER"); + + b.Property("NetworkPath") + .HasColumnType("TEXT"); + + b.Property("Path") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("JellyfinLibraryId"); + + b.ToTable("JellyfinPathInfo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("ShouldSyncItems") + .HasColumnType("INTEGER"); + + b.ToTable("EmbyLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.Property("ShouldSyncItems") + .HasColumnType("INTEGER"); + + b.ToTable("JellyfinLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.ToTable("LocalLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Library"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("ShouldSyncItems") + .HasColumnType("INTEGER"); + + b.ToTable("PlexLibrary", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaFile"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("PlexId") + .HasColumnType("INTEGER"); + + b.ToTable("PlexMediaFile", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Artist", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.HasIndex("SeasonId"); + + b.ToTable("Episode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Image", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Movie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.HasIndex("ArtistId"); + + b.ToTable("MusicVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("OtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("ShowId") + .HasColumnType("INTEGER"); + + b.HasIndex("ShowId"); + + b.ToTable("Season", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Show", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaItem"); + + b.ToTable("Song", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("TEXT"); + + b.Property("OperatingSystem") + .HasColumnType("TEXT"); + + b.Property("ServerName") + .HasColumnType("TEXT"); + + b.ToTable("EmbyMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("LastCollectionsScan") + .HasColumnType("TEXT"); + + b.Property("OperatingSystem") + .HasColumnType("TEXT"); + + b.Property("ServerName") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.ToTable("LocalMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.MediaSource"); + + b.Property("ClientIdentifier") + .HasColumnType("TEXT"); + + b.Property("LastCollectionsScan") + .HasColumnType("TEXT"); + + b.Property("Platform") + .HasColumnType("TEXT"); + + b.Property("PlatformVersion") + .HasColumnType("TEXT"); + + b.Property("ProductVersion") + .HasColumnType("TEXT"); + + b.Property("ServerName") + .HasColumnType("TEXT"); + + b.ToTable("PlexMediaSource", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("DiscardToFillAttempts") + .HasColumnType("INTEGER"); + + b.Property("PlayoutDuration") + .HasColumnType("TEXT"); + + b.Property("TailMode") + .HasColumnType("INTEGER"); + + b.ToTable("ProgramScheduleDurationItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleFloodItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.Property("Count") + .HasColumnType("INTEGER"); + + b.ToTable("ProgramScheduleMultipleItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.ProgramScheduleItem"); + + b.ToTable("ProgramScheduleOneItem", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbyEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Episode"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexEpisode", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbyMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Movie"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexMovie", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.OtherVideo"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexOtherVideo", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbySeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Season"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexSeason", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("EmbyShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("ItemId") + .HasColumnType("TEXT"); + + b.ToTable("JellyfinShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasBaseType("ErsatzTV.Core.Domain.Show"); + + b.Property("Etag") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.ToTable("PlexShow", (string)null); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Actors") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Artwork", "Artwork") + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Actor", "ArtworkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Actors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Actors") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Actors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Actors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Actors") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Actors") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Actors") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Artwork"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("ArtistMetadata") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artwork", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Channel", null) + .WithMany("Artwork") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Artwork") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Artwork") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Artwork") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Artwork") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.HasOne("ErsatzTV.Core.Domain.FFmpegProfile", "FFmpegProfile") + .WithMany() + .HasForeignKey("FFmpegProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("FFmpegProfile"); + + b.Navigation("FallbackFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.CollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("CollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("CollectionItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Director", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Directors") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Directors") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Directors") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("Connections") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyMediaSource", "EmbyMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("EmbyMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EmbyMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", "Episode") + .WithMany("EpisodeMetadata") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Episode"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.FFmpegProfile", b => + { + b.HasOne("ErsatzTV.Core.Domain.Resolution", "Resolution") + .WithMany() + .HasForeignKey("ResolutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Resolution"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Filler.FillerPreset", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Genre", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Genres") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Genres") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Genres") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Genres") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Genres") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Genres") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Genres") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Genres") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageFolderDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithOne("ImageFolderDuration") + .HasForeignKey("ErsatzTV.Core.Domain.ImageFolderDuration", "LibraryFolderId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("LibraryFolder"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Image", "Image") + .WithMany("ImageMetadata") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("Connections") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinMediaSource", "JellyfinMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("JellyfinMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JellyfinMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", "MediaSource") + .WithMany("Libraries") + .HasForeignKey("MediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("LibraryFolders") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("LibraryPath"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", "Library") + .WithMany("Paths") + .HasForeignKey("LibraryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Library"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaChapter", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Chapters") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryFolder", "LibraryFolder") + .WithMany("MediaFiles") + .HasForeignKey("LibraryFolderId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("MediaFiles") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryFolder"); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.LibraryPath", "LibraryPath") + .WithMany("MediaItems") + .HasForeignKey("LibraryPathId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LibraryPath"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaStream", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaVersion", "MediaVersion") + .WithMany("Streams") + .HasForeignKey("MediaVersionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaVersion"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithMany("MediaVersions") + .HasForeignKey("EpisodeId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Image", null) + .WithMany("MediaVersions") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithMany("MediaVersions") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithMany("MediaVersions") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Song", null) + .WithMany("MediaVersions") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MetadataGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Guids") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Guids") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Guids") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Guids") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Guids") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Guids") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Guids") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Guids") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Mood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Moods") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", "Movie") + .WithMany("MovieMetadata") + .HasForeignKey("MovieId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Movie"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany("MultiCollectionItems") + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Collection"); + + b.Navigation("MultiCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollectionSmartItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany("MultiCollectionSmartItems") + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoArtist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Artists") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.MusicVideo", "MusicVideo") + .WithMany("MusicVideoMetadata") + .HasForeignKey("MusicVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MusicVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", "OtherVideo") + .WithMany("OtherVideoMetadata") + .HasForeignKey("OtherVideoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("OtherVideo"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlaylistGroup", "PlaylistGroup") + .WithMany("Playlists") + .HasForeignKey("PlaylistGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlaylistGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany("Items") + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.HasOne("ErsatzTV.Core.Domain.Channel", "Channel") + .WithMany("Playouts") + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany("Playouts") + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Playouts") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.PlayoutAnchor", "Anchor", b1 => + { + b1.Property("PlayoutId") + .HasColumnType("INTEGER"); + + b1.Property("DurationFinish") + .HasColumnType("TEXT"); + + b1.Property("InDurationFiller") + .HasColumnType("INTEGER"); + + b1.Property("InFlood") + .HasColumnType("INTEGER"); + + b1.Property("MultipleRemaining") + .HasColumnType("INTEGER"); + + b1.Property("NextGuideGroup") + .HasColumnType("INTEGER"); + + b1.Property("NextStart") + .HasColumnType("TEXT"); + + b1.HasKey("PlayoutId"); + + b1.ToTable("PlayoutAnchor", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutId"); + + b1.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "ScheduleItemsEnumeratorState", b2 => + { + b2.Property("PlayoutAnchorPlayoutId") + .HasColumnType("INTEGER"); + + b2.Property("Index") + .HasColumnType("INTEGER"); + + b2.Property("Seed") + .HasColumnType("INTEGER"); + + b2.HasKey("PlayoutAnchorPlayoutId"); + + b2.ToTable("ScheduleItemsEnumeratorState", (string)null); + + b2.WithOwner() + .HasForeignKey("PlayoutAnchorPlayoutId"); + }); + + b1.Navigation("ScheduleItemsEnumeratorState"); + }); + + b.Navigation("Anchor"); + + b.Navigation("Channel"); + + b.Navigation("Deco"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Items") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("MediaItem"); + + b.Navigation("Playout"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutProgramScheduleAnchor", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAnchors") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutProgramScheduleAnchorId") + .HasColumnType("INTEGER"); + + b1.Property("Index") + .HasColumnType("INTEGER"); + + b1.Property("Seed") + .HasColumnType("INTEGER"); + + b1.HasKey("PlayoutProgramScheduleAnchorId"); + + b1.ToTable("CollectionEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutProgramScheduleAnchorId"); + }); + + b.Navigation("Collection"); + + b.Navigation("EnumeratorState"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("Playout"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlayoutScheduleItemFillGroupIndex", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("FillGroupIndices") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", "ProgramScheduleItem") + .WithMany() + .HasForeignKey("ProgramScheduleItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("ErsatzTV.Core.Domain.CollectionEnumeratorState", "EnumeratorState", b1 => + { + b1.Property("PlayoutScheduleItemFillGroupIndexId") + .HasColumnType("INTEGER"); + + b1.Property("Index") + .HasColumnType("INTEGER"); + + b1.Property("Seed") + .HasColumnType("INTEGER"); + + b1.HasKey("PlayoutScheduleItemFillGroupIndexId"); + + b1.ToTable("FillGroupEnumeratorState", (string)null); + + b1.WithOwner() + .HasForeignKey("PlayoutScheduleItemFillGroupIndexId"); + }); + + b.Navigation("EnumeratorState"); + + b.Navigation("Playout"); + + b.Navigation("ProgramScheduleItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexConnection", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("Connections") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexPathReplacement", b => + { + b.HasOne("ErsatzTV.Core.Domain.PlexMediaSource", "PlexMediaSource") + .WithMany("PathReplacements") + .HasForeignKey("PlexMediaSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlexMediaSource"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleAlternate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("ProgramScheduleAlternates") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Playout"); + + b.Navigation("ProgramSchedule"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "FallbackFiller") + .WithMany() + .HasForeignKey("FallbackFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "MidRollFiller") + .WithMany() + .HasForeignKey("MidRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Playlist", "Playlist") + .WithMany() + .HasForeignKey("PlaylistId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PostRollFiller") + .WithMany() + .HasForeignKey("PostRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "PreRollFiller") + .WithMany() + .HasForeignKey("PreRollFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ProgramSchedule", "ProgramSchedule") + .WithMany("Items") + .HasForeignKey("ProgramScheduleId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Filler.FillerPreset", "TailFiller") + .WithMany() + .HasForeignKey("TailFillerId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Collection"); + + b.Navigation("FallbackFiller"); + + b.Navigation("MediaItem"); + + b.Navigation("MidRollFiller"); + + b.Navigation("MultiCollection"); + + b.Navigation("Playlist"); + + b.Navigation("PostRollFiller"); + + b.Navigation("PreRollFiller"); + + b.Navigation("ProgramSchedule"); + + b.Navigation("SmartCollection"); + + b.Navigation("TailFiller"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.BlockGroup", "BlockGroup") + .WithMany("Blocks") + .HasForeignKey("BlockGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BlockGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("Items") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Collection", "Collection") + .WithMany() + .HasForeignKey("CollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany() + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "MultiCollection") + .WithMany() + .HasForeignKey("MultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "SmartCollection") + .WithMany() + .HasForeignKey("SmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("Block"); + + b.Navigation("Collection"); + + b.Navigation("MediaItem"); + + b.Navigation("MultiCollection"); + + b.Navigation("SmartCollection"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.HasOne("ErsatzTV.Core.Domain.Collection", "DeadAirFallbackCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "DeadAirFallbackMediaItem") + .WithMany() + .HasForeignKey("DeadAirFallbackMediaItemId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MultiCollection", "DeadAirFallbackMultiCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackMultiCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SmartCollection", "DeadAirFallbackSmartCollection") + .WithMany() + .HasForeignKey("DeadAirFallbackSmartCollectionId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoGroup", "DecoGroup") + .WithMany("Decos") + .HasForeignKey("DecoGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.ChannelWatermark", "Watermark") + .WithMany() + .HasForeignKey("WatermarkId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("DeadAirFallbackCollection"); + + b.Navigation("DeadAirFallbackMediaItem"); + + b.Navigation("DeadAirFallbackMultiCollection"); + + b.Navigation("DeadAirFallbackSmartCollection"); + + b.Navigation("DecoGroup"); + + b.Navigation("Watermark"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", "DecoTemplateGroup") + .WithMany("DecoTemplates") + .HasForeignKey("DecoTemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Deco", "Deco") + .WithMany() + .HasForeignKey("DecoId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("Items") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Deco"); + + b.Navigation("DecoTemplate"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutHistory", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("PlayoutHistory") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("PlayoutHistory") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Playout"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.PlayoutTemplate", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", "DecoTemplate") + .WithMany("PlayoutTemplates") + .HasForeignKey("DecoTemplateId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.Playout", "Playout") + .WithMany("Templates") + .HasForeignKey("PlayoutId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("PlayoutTemplates") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DecoTemplate"); + + b.Navigation("Playout"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", "TemplateGroup") + .WithMany("Templates") + .HasForeignKey("TemplateGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TemplateGroup"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Block", "Block") + .WithMany("TemplateItems") + .HasForeignKey("BlockId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Scheduling.Template", "Template") + .WithMany("Items") + .HasForeignKey("TemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Block"); + + b.Navigation("Template"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("SeasonMetadata") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("ShowMetadata") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.HasOne("ErsatzTV.Core.Domain.Song", "Song") + .WithMany("SongMetadata") + .HasForeignKey("SongId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Song"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Studio", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Studios") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Studios") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Studios") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Studios") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Studios") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Studios") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Studios") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Studios") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Style", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Styles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Subtitle", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Subtitles") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Tag", b => + { + b.HasOne("ErsatzTV.Core.Domain.ArtistMetadata", null) + .WithMany("Tags") + .HasForeignKey("ArtistMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Tags") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ImageMetadata", null) + .WithMany("Tags") + .HasForeignKey("ImageMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Tags") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MusicVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("MusicVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Tags") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SeasonMetadata", null) + .WithMany("Tags") + .HasForeignKey("SeasonMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.ShowMetadata", null) + .WithMany("Tags") + .HasForeignKey("ShowMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.SongMetadata", null) + .WithMany("Tags") + .HasForeignKey("SongMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", "MediaItem") + .WithMany("TraktListItems") + .HasForeignKey("MediaItemId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("ErsatzTV.Core.Domain.TraktList", "TraktList") + .WithMany("Items") + .HasForeignKey("TraktListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MediaItem"); + + b.Navigation("TraktList"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItemGuid", b => + { + b.HasOne("ErsatzTV.Core.Domain.TraktListItem", "TraktListItem") + .WithMany("Guids") + .HasForeignKey("TraktListItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("TraktListItem"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Writer", b => + { + b.HasOne("ErsatzTV.Core.Domain.EpisodeMetadata", null) + .WithMany("Writers") + .HasForeignKey("EpisodeMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.MovieMetadata", null) + .WithMany("Writers") + .HasForeignKey("MovieMetadataId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("ErsatzTV.Core.Domain.OtherVideoMetadata", null) + .WithMany("Writers") + .HasForeignKey("OtherVideoMetadataId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Emby.EmbyPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.EmbyLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("EmbyLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Jellyfin.JellyfinPathInfo", b => + { + b.HasOne("ErsatzTV.Core.Domain.JellyfinLibrary", null) + .WithMany("PathInfos") + .HasForeignKey("JellyfinLibraryId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexLibrary", b => + { + b.HasOne("ErsatzTV.Core.Domain.Library", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexLibrary", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaFile", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaFile", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaFile", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Artist", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Episode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Season", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Image", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Movie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.Artist", "Artist") + .WithMany("MusicVideos") + .HasForeignKey("ArtistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.MusicVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Artist"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.OtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Season", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ErsatzTV.Core.Domain.Show", "Show") + .WithMany("Seasons") + .HasForeignKey("ShowId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Show"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Show", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.Song", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LocalMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.LocalMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.HasOne("ErsatzTV.Core.Domain.MediaSource", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMediaSource", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemDuration", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemFlood", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemMultiple", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramScheduleItemOne", b => + { + b.HasOne("ErsatzTV.Core.Domain.ProgramScheduleItem", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.ProgramScheduleItemOne", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexEpisode", b => + { + b.HasOne("ErsatzTV.Core.Domain.Episode", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexEpisode", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMovie", b => + { + b.HasOne("ErsatzTV.Core.Domain.Movie", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexMovie", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexOtherVideo", b => + { + b.HasOne("ErsatzTV.Core.Domain.OtherVideo", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexOtherVideo", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbySeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbySeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexSeason", b => + { + b.HasOne("ErsatzTV.Core.Domain.Season", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexSeason", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.EmbyShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.JellyfinShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexShow", b => + { + b.HasOne("ErsatzTV.Core.Domain.Show", null) + .WithOne() + .HasForeignKey("ErsatzTV.Core.Domain.PlexShow", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ArtistMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Moods"); + + b.Navigation("Studios"); + + b.Navigation("Styles"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Channel", b => + { + b.Navigation("Artwork"); + + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Collection", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("MultiCollectionItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EpisodeMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ImageMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Library", b => + { + b.Navigation("Paths"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryFolder", b => + { + b.Navigation("Children"); + + b.Navigation("ImageFolderDuration"); + + b.Navigation("MediaFiles"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.LibraryPath", b => + { + b.Navigation("LibraryFolders"); + + b.Navigation("MediaItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaItem", b => + { + b.Navigation("CollectionItems"); + + b.Navigation("TraktListItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaSource", b => + { + b.Navigation("Libraries"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MediaVersion", b => + { + b.Navigation("Chapters"); + + b.Navigation("MediaFiles"); + + b.Navigation("Streams"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MovieMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MultiCollection", b => + { + b.Navigation("MultiCollectionItems"); + + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artists"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideoMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Directors"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + + b.Navigation("Writers"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playlist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlaylistGroup", b => + { + b.Navigation("Playlists"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Playout", b => + { + b.Navigation("FillGroupIndices"); + + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("ProgramScheduleAlternates"); + + b.Navigation("ProgramScheduleAnchors"); + + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ProgramSchedule", b => + { + b.Navigation("Items"); + + b.Navigation("Playouts"); + + b.Navigation("ProgramScheduleAlternates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Block", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutHistory"); + + b.Navigation("TemplateItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.BlockGroup", b => + { + b.Navigation("Blocks"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Deco", b => + { + b.Navigation("Playouts"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoGroup", b => + { + b.Navigation("Decos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplate", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.DecoTemplateGroup", b => + { + b.Navigation("DecoTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.Template", b => + { + b.Navigation("Items"); + + b.Navigation("PlayoutTemplates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Scheduling.TemplateGroup", b => + { + b.Navigation("Templates"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SeasonMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.ShowMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SmartCollection", b => + { + b.Navigation("MultiCollectionSmartItems"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.SongMetadata", b => + { + b.Navigation("Actors"); + + b.Navigation("Artwork"); + + b.Navigation("Genres"); + + b.Navigation("Guids"); + + b.Navigation("Studios"); + + b.Navigation("Subtitles"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktList", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.TraktListItem", b => + { + b.Navigation("Guids"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinLibrary", b => + { + b.Navigation("PathInfos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Artist", b => + { + b.Navigation("ArtistMetadata"); + + b.Navigation("MusicVideos"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Episode", b => + { + b.Navigation("EpisodeMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Image", b => + { + b.Navigation("ImageMetadata"); + + b.Navigation("MediaVersions"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Movie", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MovieMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.MusicVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("MusicVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.OtherVideo", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("OtherVideoMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Season", b => + { + b.Navigation("Episodes"); + + b.Navigation("SeasonMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Show", b => + { + b.Navigation("Seasons"); + + b.Navigation("ShowMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.Song", b => + { + b.Navigation("MediaVersions"); + + b.Navigation("SongMetadata"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.EmbyMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.JellyfinMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); + + modelBuilder.Entity("ErsatzTV.Core.Domain.PlexMediaSource", b => + { + b.Navigation("Connections"); + + b.Navigation("PathReplacements"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.cs b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.cs new file mode 100644 index 00000000..32e03cee --- /dev/null +++ b/ErsatzTV.Infrastructure.Sqlite/Migrations/20240716150019_Add_Playout_OnDemandCheckpoint.cs @@ -0,0 +1,29 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ErsatzTV.Infrastructure.Sqlite.Migrations +{ + /// + public partial class Add_Playout_OnDemandCheckpoint : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "OnDemandCheckpoint", + table: "Playout", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "OnDemandCheckpoint", + table: "Playout"); + } + } +} diff --git a/ErsatzTV.Infrastructure.Sqlite/Migrations/TvContextModelSnapshot.cs b/ErsatzTV.Infrastructure.Sqlite/Migrations/TvContextModelSnapshot.cs index f251dd79..23ab0aec 100644 --- a/ErsatzTV.Infrastructure.Sqlite/Migrations/TvContextModelSnapshot.cs +++ b/ErsatzTV.Infrastructure.Sqlite/Migrations/TvContextModelSnapshot.cs @@ -15,7 +15,7 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.5"); + modelBuilder.HasAnnotation("ProductVersion", "8.0.7"); modelBuilder.Entity("ErsatzTV.Core.Domain.Actor", b => { @@ -264,6 +264,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations b.Property("PreferredSubtitleLanguageCode") .HasColumnType("TEXT"); + b.Property("ProgressMode") + .HasColumnType("INTEGER"); + b.Property("StreamingMode") .HasColumnType("INTEGER"); @@ -1612,6 +1615,9 @@ namespace ErsatzTV.Infrastructure.Sqlite.Migrations b.Property("ExternalJsonFile") .HasColumnType("TEXT"); + b.Property("OnDemandCheckpoint") + .HasColumnType("TEXT"); + b.Property("ProgramScheduleId") .HasColumnType("INTEGER"); diff --git a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj index 076bdbd0..c0844eb4 100644 --- a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj +++ b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj @@ -13,24 +13,24 @@ - - + + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + diff --git a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj index 95b6bb48..cb8f3bef 100644 --- a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj +++ b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj index bbd4f559..a034d05a 100644 --- a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj +++ b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj @@ -22,17 +22,17 @@ - - + + - + - - - + + + diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj index e8fd209b..1345a422 100644 --- a/ErsatzTV/ErsatzTV.csproj +++ b/ErsatzTV/ErsatzTV.csproj @@ -16,20 +16,20 @@ - + - + - + - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -37,12 +37,12 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + - - + + - + diff --git a/ErsatzTV/Pages/ChannelEditor.razor b/ErsatzTV/Pages/ChannelEditor.razor index 2291e4a0..2b73af85 100644 --- a/ErsatzTV/Pages/ChannelEditor.razor +++ b/ErsatzTV/Pages/ChannelEditor.razor @@ -30,6 +30,10 @@ + + Always + On Demand + MPEG-TS MPEG-TS (Legacy) @@ -180,6 +184,7 @@ _model.Number = channelViewModel.Number; _model.FFmpegProfileId = channelViewModel.FFmpegProfileId; _model.Logo = channelViewModel.Logo; + _model.ProgressMode = channelViewModel.ProgressMode; _model.StreamingMode = channelViewModel.StreamingMode; _model.PreferredAudioLanguageCode = channelViewModel.PreferredAudioLanguageCode; _model.PreferredAudioTitle = channelViewModel.PreferredAudioTitle; diff --git a/ErsatzTV/Pages/Playouts.razor b/ErsatzTV/Pages/Playouts.razor index 6bb85c85..e6e76902 100644 --- a/ErsatzTV/Pages/Playouts.razor +++ b/ErsatzTV/Pages/Playouts.razor @@ -81,12 +81,24 @@ @if (context.PlayoutType == ProgramSchedulePlayoutType.Flood) { - - - - + if (context.ProgressMode is ChannelProgressMode.OnDemand) + { + + + + + } + else + { + + + + + } + (); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/ErsatzTV/ViewModels/ChannelEditViewModel.cs b/ErsatzTV/ViewModels/ChannelEditViewModel.cs index ebf95418..feb62b7b 100644 --- a/ErsatzTV/ViewModels/ChannelEditViewModel.cs +++ b/ErsatzTV/ViewModels/ChannelEditViewModel.cs @@ -15,6 +15,7 @@ public class ChannelEditViewModel public string PreferredAudioLanguageCode { get; set; } public string PreferredAudioTitle { get; set; } public string Logo { get; set; } + public ChannelProgressMode ProgressMode { get; set; } public StreamingMode StreamingMode { get; set; } public int? WatermarkId { get; set; } public int? FallbackFillerId { get; set; } @@ -41,6 +42,7 @@ public class ChannelEditViewModel Logo, PreferredAudioLanguageCode, PreferredAudioTitle, + ProgressMode, StreamingMode, WatermarkId, FallbackFillerId, @@ -59,6 +61,7 @@ public class ChannelEditViewModel Logo, PreferredAudioLanguageCode, PreferredAudioTitle, + ProgressMode, StreamingMode, WatermarkId, FallbackFillerId,