aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Controller/Entities
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-05-12 22:50:16 +0200
committerShadowghost <Ghost_of_Stone@web.de>2026-05-12 22:50:16 +0200
commit8f7c54ee5ef8647bc049499819606ad7946378ec (patch)
tree4411b82fd0d0660a426b869a5781782e6dee7500 /MediaBrowser.Controller/Entities
parent5e82b61bab8c9461624fd2095fc9ccd11e33ce8d (diff)
parente9942c385775f33c70dbb4b910085ae2c563e898 (diff)
Merge remote-tracking branch 'upstream/master' into search-rebased
Diffstat (limited to 'MediaBrowser.Controller/Entities')
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs82
2 files changed, 72 insertions, 13 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 822b21c062..4cdcaabbb1 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -216,6 +216,9 @@ namespace MediaBrowser.Controller.Entities
[JsonIgnore]
public string OriginalTitle { get; set; }
+ [JsonIgnore]
+ public string OriginalLanguage { get; set; }
+
/// <summary>
/// Gets or sets the id.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 3b20dc85fe..5fa1213db3 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1593,17 +1593,11 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
public List<BaseItem> GetLinkedChildren()
{
- var linkedChildren = LinkedChildren;
- var list = new List<BaseItem>(linkedChildren.Length);
-
- foreach (var i in linkedChildren)
+ var resolved = ResolveLinkedChildren(LinkedChildren);
+ var list = new List<BaseItem>(resolved.Count);
+ foreach (var (_, item) in resolved)
{
- var child = GetLinkedChild(i);
-
- if (child is not null)
- {
- list.Add(child);
- }
+ list.Add(item);
}
return list;
@@ -1704,12 +1698,74 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetLinkedChildrenInfos()
{
- return LinkedChildren
- .Select(i => new Tuple<LinkedChild, BaseItem>(i, GetLinkedChild(i)))
- .Where(i => i.Item2 is not null)
+ return ResolveLinkedChildren(LinkedChildren)
+ .Select(t => new Tuple<LinkedChild, BaseItem>(t.Info, t.Item))
.ToArray();
}
+ /// <summary>
+ /// Resolves a list of <see cref="LinkedChild"/> entries to their <see cref="BaseItem"/> targets,
+ /// batching the database lookup across all entries with a known ItemId.
+ /// Entries without a usable ItemId fall back to the per-entry <see cref="BaseItem.GetLinkedChild"/>
+ /// path (legacy path-based resolution).
+ /// </summary>
+ /// <param name="linkedChildren">Linked children to resolve.</param>
+ /// <returns>Each input entry paired with its resolved item; entries that fail to resolve are dropped.</returns>
+ private List<(LinkedChild Info, BaseItem Item)> ResolveLinkedChildren(IReadOnlyList<LinkedChild> linkedChildren)
+ {
+ var resolved = new List<(LinkedChild Info, BaseItem Item)>(linkedChildren.Count);
+ if (linkedChildren.Count == 0)
+ {
+ return resolved;
+ }
+
+ var idsToBatch = new HashSet<Guid>();
+ foreach (var info in linkedChildren)
+ {
+ if (info.ItemId.HasValue && !info.ItemId.Value.IsEmpty())
+ {
+ idsToBatch.Add(info.ItemId.Value);
+ }
+ }
+
+ Dictionary<Guid, BaseItem> byId = null;
+ if (idsToBatch.Count > 0)
+ {
+ var batched = LibraryManager.GetItemList(new InternalItemsQuery
+ {
+ ItemIds = [.. idsToBatch]
+ });
+ byId = new Dictionary<Guid, BaseItem>(batched.Count);
+ foreach (var item in batched)
+ {
+ byId[item.Id] = item;
+ }
+ }
+
+ foreach (var info in linkedChildren)
+ {
+ BaseItem item = null;
+ if (byId is not null && info.ItemId.HasValue && byId.TryGetValue(info.ItemId.Value, out var batchedItem))
+ {
+ item = batchedItem;
+ }
+ else
+ {
+ // ItemId is missing/empty or the batched query couldn't return the item
+ // (e.g. it has been removed). Fall back to per-entry resolution, which also
+ // handles legacy path-based linked children.
+ item = GetLinkedChild(info);
+ }
+
+ if (item is not null)
+ {
+ resolved.Add((info, item));
+ }
+ }
+
+ return resolved;
+ }
+
protected override async Task<bool> RefreshedOwnedItems(MetadataRefreshOptions options, IReadOnlyList<FileSystemMetadata> fileSystemChildren, CancellationToken cancellationToken)
{
var changesFound = false;