Compare commits

...

3 Commits

Author SHA1 Message Date
Cody Robibero
45d51568e7 perf 2025-12-14 11:32:19 -07:00
Cody Robibero
c370de77de Manually map instead of relying on changetracker 2025-12-14 10:55:39 -07:00
Cody Robibero
f6709a69e7 Explicitly load related items 2025-12-14 10:08:33 -07:00

View File

@@ -275,9 +275,8 @@ public sealed class BaseItemRepository
}
dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
result.Items = dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
result.Items = GetEntities(dbQuery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
result.StartIndex = filter.StartIndex ?? 0;
return result;
}
@@ -295,9 +294,8 @@ public sealed class BaseItemRepository
dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
return dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
return GetEntities(dbQuery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
}
/// <inheritdoc/>
@@ -339,9 +337,7 @@ public sealed class BaseItemRepository
mainquery = ApplyGroupingFilter(context, mainquery, filter);
mainquery = ApplyQueryPaging(mainquery, filter);
mainquery = ApplyNavigations(mainquery, filter);
return mainquery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
return GetEntities(mainquery, context, filter).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
}
/// <inheritdoc />
@@ -408,36 +404,6 @@ public sealed class BaseItemRepository
return dbQuery;
}
private static IQueryable<BaseItemEntity> ApplyNavigations(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{
if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
{
dbQuery = dbQuery.Include(e => e.TrailerTypes);
}
if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds))
{
dbQuery = dbQuery.Include(e => e.Provider);
}
if (filter.DtoOptions.ContainsField(ItemFields.Settings))
{
dbQuery = dbQuery.Include(e => e.LockedFields);
}
if (filter.DtoOptions.EnableUserData)
{
dbQuery = dbQuery.Include(e => e.UserData);
}
if (filter.DtoOptions.EnableImages)
{
dbQuery = dbQuery.Include(e => e.Images);
}
return dbQuery;
}
private IQueryable<BaseItemEntity> ApplyQueryPaging(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
{
if (filter.Limit.HasValue || filter.StartIndex.HasValue)
@@ -463,7 +429,6 @@ public sealed class BaseItemRepository
dbQuery = TranslateQuery(dbQuery, context, filter);
dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
dbQuery = ApplyQueryPaging(dbQuery, filter);
dbQuery = ApplyNavigations(dbQuery, filter);
return dbQuery;
}
@@ -475,6 +440,79 @@ public sealed class BaseItemRepository
return dbQuery;
}
private IReadOnlyList<BaseItemEntity> GetEntities(IQueryable<BaseItemEntity> dbQuery, JellyfinDbContext context, InternalItemsQuery filter)
{
var items = dbQuery.Where(e => e != null).ToDictionary(e => e.Id, e => e);
var itemIds = items.Keys.ToArray();
if (itemIds.Length == 0)
{
return [];
}
if (filter.TrailerTypes.Length > 0 || filter.IncludeItemTypes.Contains(BaseItemKind.Trailer))
{
var values = context.BaseItemTrailerTypes.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.TrailerTypes = value.ToArray();
}
}
}
if (filter.DtoOptions.ContainsField(ItemFields.ProviderIds))
{
var values = context.BaseItemProviders.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.Provider = value.ToArray();
}
}
}
if (filter.DtoOptions.ContainsField(ItemFields.Settings))
{
var values = context.BaseItemMetadataFields.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.LockedFields = value.ToArray();
}
}
}
if (filter.DtoOptions.EnableImages)
{
var values = context.BaseItemImageInfos.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.Images = value.ToArray();
}
}
}
if (filter.DtoOptions.EnableUserData)
{
var values = context.UserData.WhereOneOrMany(itemIds, e => e.ItemId).GroupBy(x => x.ItemId).ToArray();
foreach (var value in values)
{
if (items.TryGetValue(value.Key, out var item))
{
item.UserData = value.ToArray();
}
}
}
return items.Values.ToArray();
}
/// <inheritdoc/>
public int GetCount(InternalItemsQuery filter)
{