diff options
| author | Shadowghost <Ghost_of_Stone@web.de> | 2026-01-17 17:10:07 +0100 |
|---|---|---|
| committer | Shadowghost <Ghost_of_Stone@web.de> | 2026-01-18 19:48:46 +0100 |
| commit | 5996c4afce11249804d24f1caa3a99b390543c4d (patch) | |
| tree | d84b98428d95c801492b1354571e2ab3fc0cc99b /MediaBrowser.Controller/Entities/Video.cs | |
| parent | dfa78590c2899c7e74b142ebbced4140a354aed0 (diff) | |
Complete LinkedChildren integration and batch DTO optimizations
This commit integrates remaining performance changes:
- Add batch user data fetching in DtoService to reduce N+1 queries
- Add GetNextUpEpisodesBatch in TVSeriesManager for efficient batch retrieval
- Update Video/Movie/BoxSet to use LibraryManager for alternate versions
- Transition LinkedChild to use ItemId instead of Path (obsolete Path/LibraryItemId)
- Update providers and controllers for LinkedChildren-based references
- Add NextUpEpisodeBatchResult for batched episode queries
- Integrate IDescendantQueryProvider in SqliteDatabaseProvider
Diffstat (limited to 'MediaBrowser.Controller/Entities/Video.cs')
| -rw-r--r-- | MediaBrowser.Controller/Entities/Video.cs | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 1043029c6e..1ddc193359 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -160,7 +160,7 @@ namespace MediaBrowser.Controller.Entities public bool IsStacked => AdditionalParts.Length > 0; [JsonIgnore] - public override bool HasLocalAlternateVersions => LocalAlternateVersions.Length > 0; + public override bool HasLocalAlternateVersions => LibraryManager.GetLocalAlternateVersionIds(this).Any(); public static IRecordingsManager RecordingsManager { get; set; } @@ -260,7 +260,10 @@ namespace MediaBrowser.Controller.Entities { if (callstack.Contains(video.Id)) { - return video.LinkedAlternateVersions.Length + video.LocalAlternateVersions.Length + 1; + // Count alternate versions using LibraryManager + var linkedCount = LibraryManager.GetLinkedAlternateVersions(video).Count(); + var localCount = LibraryManager.GetLocalAlternateVersionIds(video).Count(); + return linkedCount + localCount + 1; } callstack.Add(video.Id); @@ -268,7 +271,10 @@ namespace MediaBrowser.Controller.Entities } } - return LinkedAlternateVersions.Length + LocalAlternateVersions.Length + 1; + // Count alternate versions using LibraryManager + var linkedVersionCount = LibraryManager.GetLinkedAlternateVersions(this).Count(); + var localVersionCount = LibraryManager.GetLocalAlternateVersionIds(this).Count(); + return linkedVersionCount + localVersionCount + 1; } public override List<string> GetUserDataKeys() @@ -364,11 +370,6 @@ namespace MediaBrowser.Controller.Entities return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); } - public IEnumerable<Guid> GetLocalAlternateVersionIds() - { - return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); - } - private string GetUserDataKey(string providerId) { var key = providerId + "-" + ExtraType.ToString().ToLowerInvariant(); @@ -382,15 +383,6 @@ namespace MediaBrowser.Controller.Entities return key; } - public IEnumerable<Video> GetLinkedAlternateVersions() - { - return LinkedAlternateVersions - .Select(GetLinkedChild) - .Where(i => i is not null) - .OfType<Video>() - .OrderBy(i => i.SortName); - } - /// <summary> /// Gets the additional parts. /// </summary> @@ -454,7 +446,7 @@ namespace MediaBrowser.Controller.Entities RefreshLinkedAlternateVersions(); var tasks = LocalAlternateVersions - .Select(i => RefreshMetadataForOwnedVideo(options, false, i, cancellationToken)); + .Select(i => RefreshMetadataForVersions(options, false, i, cancellationToken)); await Task.WhenAll(tasks).ConfigureAwait(false); } @@ -463,6 +455,39 @@ namespace MediaBrowser.Controller.Entities return hasChanges; } + protected virtual async Task RefreshMetadataForVersions(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken) + { + await RefreshMetadataForOwnedVideo(options, copyTitleMetadata, path, cancellationToken).ConfigureAwait(false); + } + + private new async Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, bool copyTitleMetadata, string path, CancellationToken cancellationToken) + { + var newOptions = new MetadataRefreshOptions(options) + { + SearchResult = null + }; + + var id = LibraryManager.GetNewItemId(path, typeof(Video)); + if (LibraryManager.GetItemById(id) is not Video video) + { + video = LibraryManager.ResolvePath(FileSystem.GetFileSystemInfo(path)) as Video; + + newOptions.ForceSave = true; + } + + if (video is null) + { + return; + } + + if (video.OwnerId.IsEmpty()) + { + video.OwnerId = Id; + } + + await RefreshMetadataForOwnedItem(video, copyTitleMetadata, newOptions, cancellationToken).ConfigureAwait(false); + } + private void RefreshLinkedAlternateVersions() { foreach (var child in LinkedAlternateVersions) @@ -480,7 +505,7 @@ namespace MediaBrowser.Controller.Entities { await base.UpdateToRepositoryAsync(updateReason, cancellationToken).ConfigureAwait(false); - var localAlternates = GetLocalAlternateVersionIds() + var localAlternates = LibraryManager.GetLocalAlternateVersionIds(this) .Select(i => LibraryManager.GetItemById(i)) .Where(i => i is not null); @@ -537,7 +562,7 @@ namespace MediaBrowser.Controller.Entities (this, MediaSourceType.Default) }; - list.AddRange(GetLinkedAlternateVersions().Select(i => ((BaseItem)i, MediaSourceType.Grouping))); + list.AddRange(LibraryManager.GetLinkedAlternateVersions(this).Select(i => ((BaseItem)i, MediaSourceType.Grouping))); if (!string.IsNullOrEmpty(PrimaryVersionId)) { @@ -545,14 +570,14 @@ namespace MediaBrowser.Controller.Entities { var existingIds = list.Select(i => i.Item1.Id).ToList(); list.Add((primary, MediaSourceType.Grouping)); - list.AddRange(primary.GetLinkedAlternateVersions().Where(i => !existingIds.Contains(i.Id)).Select(i => ((BaseItem)i, MediaSourceType.Grouping))); + list.AddRange(LibraryManager.GetLinkedAlternateVersions(primary).Where(i => !existingIds.Contains(i.Id)).Select(i => ((BaseItem)i, MediaSourceType.Grouping))); } } var localAlternates = list .SelectMany(i => { - return i.Item1 is Video video ? video.GetLocalAlternateVersionIds() : Enumerable.Empty<Guid>(); + return i.Item1 is Video video ? LibraryManager.GetLocalAlternateVersionIds(video) : Enumerable.Empty<Guid>(); }) .Select(LibraryManager.GetItemById) .Where(i => i is not null) |
