From c370de77dea7656a8fe532eb50d595a31452d42d Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Sun, 14 Dec 2025 10:55:39 -0700 Subject: [PATCH] Manually map instead of relying on changetracker --- .../Item/BaseItemRepository.cs | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs index f7c8ceadfc..5043b0d94d 100644 --- a/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs +++ b/Jellyfin.Server.Implementations/Item/BaseItemRepository.cs @@ -434,7 +434,7 @@ public sealed class BaseItemRepository private IQueryable PrepareItemQuery(JellyfinDbContext context, InternalItemsQuery filter) { - IQueryable dbQuery = context.BaseItems; + IQueryable dbQuery = context.BaseItems.AsNoTracking(); dbQuery = dbQuery.AsSingleQuery(); return dbQuery; @@ -442,35 +442,70 @@ public sealed class BaseItemRepository private IReadOnlyList GetEntities(IQueryable dbQuery, JellyfinDbContext context, InternalItemsQuery filter) { - var items = dbQuery.AsEnumerable().Where(e => e is not null).ToArray(); - var itemIds = items.Select(e => e.Id).ToArray(); + var items = dbQuery.AsEnumerable().Where(e => e is not null).ToDictionary(e => e.Id, e => e); + var itemIds = items.Keys.ToArray(); if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer)) { - context.BaseItemTrailerTypes.WhereOneOrMany(itemIds, e => e.ItemId).Load(); + var values = context.BaseItemTrailerTypes.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId); + foreach (var value in values) + { + if (items.TryGetValue(value.Key, out var item)) + { + item.TrailerTypes = value.ToArray(); + } + } } if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds)) { - context.BaseItemProviders.WhereOneOrMany(itemIds, e => e.ItemId).Load(); + var values = context.BaseItemProviders.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId); + foreach (var value in values) + { + if (items.TryGetValue(value.Key, out var item)) + { + item.Provider = value.ToArray(); + } + } } if (filter.DtoOptions.ContainsField(ItemFields.Settings)) { - context.BaseItemMetadataFields.WhereOneOrMany(itemIds, e => e.ItemId).Load(); + var values = context.BaseItemMetadataFields.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId); + foreach (var value in values) + { + if (items.TryGetValue(value.Key, out var item)) + { + item.LockedFields = value.ToArray(); + } + } } if (filter.DtoOptions.EnableImages) { - context.BaseItemImageInfos.WhereOneOrMany(itemIds, e => e.ItemId).Load(); + var values = context.BaseItemImageInfos.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId); + foreach (var value in values) + { + if (items.TryGetValue(value.Key, out var item)) + { + item.Images = value.ToArray(); + } + } } if (filter.DtoOptions.EnableUserData) { - context.UserData.WhereOneOrMany(itemIds, e => e.ItemId).Load(); + var values = context.UserData.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId); + foreach (var value in values) + { + if (items.TryGetValue(value.Key, out var item)) + { + item.UserData = value.ToArray(); + } + } } - return items; + return items.Values.ToArray(); } ///