浏览代码

Fix groupings not applied (#14826)

JPVenson 3 天之前
父节点
当前提交
98f5e21bb8

+ 1 - 1
Emby.Server.Implementations/Library/UserDataManager.cs

@@ -238,7 +238,7 @@ namespace Emby.Server.Implementations.Library
         /// <inheritdoc />
         public UserItemData? GetUserData(User user, BaseItem item)
         {
-            return item.UserData.Where(e => e.UserId.Equals(user.Id)).Select(Map).FirstOrDefault() ?? new UserItemData()
+            return item.UserData?.Where(e => e.UserId.Equals(user.Id)).Select(Map).FirstOrDefault() ?? new UserItemData()
             {
                 Key = item.GetUserDataKeys()[0],
             };

+ 53 - 41
Jellyfin.Server.Implementations/Item/BaseItemRepository.cs

@@ -271,7 +271,7 @@ public sealed class BaseItemRepository
             result.TotalRecordCount = dbQuery.Count();
         }
 
-        dbQuery = ApplyGroupingFilter(dbQuery, filter);
+        dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
         dbQuery = ApplyQueryPaging(dbQuery, filter);
 
         result.Items = dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
@@ -290,7 +290,7 @@ public sealed class BaseItemRepository
 
         dbQuery = TranslateQuery(dbQuery, context, filter);
 
-        dbQuery = ApplyGroupingFilter(dbQuery, filter);
+        dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
         dbQuery = ApplyQueryPaging(dbQuery, filter);
 
         return dbQuery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
@@ -332,7 +332,7 @@ public sealed class BaseItemRepository
         var mainquery = PrepareItemQuery(context, filter);
         mainquery = TranslateQuery(mainquery, context, filter);
         mainquery = mainquery.Where(g => g.DateCreated >= subqueryGrouped.Min(s => s.MaxDateCreated));
-        mainquery = ApplyGroupingFilter(mainquery, filter);
+        mainquery = ApplyGroupingFilter(context, mainquery, filter);
         mainquery = ApplyQueryPaging(mainquery, filter);
 
         return mainquery.AsEnumerable().Where(e => e is not null).Select(w => DeserializeBaseItem(w, filter.SkipDeserialization)).ToArray();
@@ -369,36 +369,50 @@ public sealed class BaseItemRepository
         return query.ToArray();
     }
 
-    private IQueryable<BaseItemEntity> ApplyGroupingFilter(IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
+    private IQueryable<BaseItemEntity> ApplyGroupingFilter(JellyfinDbContext context, IQueryable<BaseItemEntity> dbQuery, InternalItemsQuery filter)
     {
         // This whole block is needed to filter duplicate entries on request
         // for the time being it cannot be used because it would destroy the ordering
         // this results in "duplicate" responses for queries that try to lookup individual series or multiple versions but
         // for that case the invoker has to run a DistinctBy(e => e.PresentationUniqueKey) on their own
 
-        // var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter);
-        // if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey)
-        // {
-        //     dbQuery = ApplyOrder(dbQuery, filter);
-        //     dbQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.First());
-        // }
-        // else if (enableGroupByPresentationUniqueKey)
-        // {
-        //     dbQuery = ApplyOrder(dbQuery, filter);
-        //     dbQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.First());
-        // }
-        // else if (filter.GroupBySeriesPresentationUniqueKey)
-        // {
-        //     dbQuery = ApplyOrder(dbQuery, filter);
-        //     dbQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.First());
-        // }
-        // else
-        // {
-        //     dbQuery = dbQuery.Distinct();
-        //     dbQuery = ApplyOrder(dbQuery, filter);
-        // }
-        dbQuery = dbQuery.Distinct();
-        dbQuery = ApplyOrder(dbQuery, filter);
+        var enableGroupByPresentationUniqueKey = EnableGroupByPresentationUniqueKey(filter);
+        if (enableGroupByPresentationUniqueKey && filter.GroupBySeriesPresentationUniqueKey)
+        {
+            var tempQuery = dbQuery.GroupBy(e => new { e.PresentationUniqueKey, e.SeriesPresentationUniqueKey }).Select(e => e.FirstOrDefault()).Select(e => e!.Id);
+            dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id));
+            dbQuery = ApplyOrder(dbQuery, filter);
+        }
+        else if (enableGroupByPresentationUniqueKey)
+        {
+            var tempQuery = dbQuery.GroupBy(e => e.PresentationUniqueKey).Select(e => e.FirstOrDefault()).Select(e => e!.Id);
+            dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id));
+            dbQuery = ApplyOrder(dbQuery, filter);
+        }
+        else if (filter.GroupBySeriesPresentationUniqueKey)
+        {
+            var tempQuery = dbQuery.GroupBy(e => e.SeriesPresentationUniqueKey).Select(e => e.FirstOrDefault()).Select(e => e!.Id);
+            dbQuery = context.BaseItems.Where(e => tempQuery.Contains(e.Id));
+            dbQuery = ApplyOrder(dbQuery, filter);
+        }
+        else
+        {
+            dbQuery = dbQuery.Distinct();
+            dbQuery = ApplyOrder(dbQuery, filter);
+        }
+
+        dbQuery = dbQuery.Include(e => e.TrailerTypes)
+           .Include(e => e.Provider)
+           .Include(e => e.LockedFields)
+           .Include(e => e.UserData);
+
+        if (filter.DtoOptions.EnableImages)
+        {
+            dbQuery = dbQuery.Include(e => e.Images);
+        }
+
+        // dbQuery = dbQuery.Distinct();
+        // dbQuery = ApplyOrder(dbQuery, filter);
 
         return dbQuery;
     }
@@ -426,8 +440,8 @@ public sealed class BaseItemRepository
     private IQueryable<BaseItemEntity> ApplyQueryFilter(IQueryable<BaseItemEntity> dbQuery, JellyfinDbContext context, InternalItemsQuery filter)
     {
         dbQuery = TranslateQuery(dbQuery, context, filter);
-        dbQuery = ApplyOrder(dbQuery, filter);
-        dbQuery = ApplyGroupingFilter(dbQuery, filter);
+        // dbQuery = ApplyOrder(dbQuery, filter);
+        dbQuery = ApplyGroupingFilter(context, dbQuery, filter);
         dbQuery = ApplyQueryPaging(dbQuery, filter);
         return dbQuery;
     }
@@ -435,16 +449,7 @@ public sealed class BaseItemRepository
     private IQueryable<BaseItemEntity> PrepareItemQuery(JellyfinDbContext context, InternalItemsQuery filter)
     {
         IQueryable<BaseItemEntity> dbQuery = context.BaseItems.AsNoTracking();
-        dbQuery = dbQuery.AsSingleQuery()
-            .Include(e => e.TrailerTypes)
-            .Include(e => e.Provider)
-            .Include(e => e.LockedFields)
-            .Include(e => e.UserData);
-
-        if (filter.DtoOptions.EnableImages)
-        {
-            dbQuery = dbQuery.Include(e => e.Images);
-        }
+        dbQuery = dbQuery.AsSingleQuery();
 
         return dbQuery;
     }
@@ -729,13 +734,20 @@ public sealed class BaseItemRepository
         }
 
         using var context = _dbProvider.CreateDbContext();
-        var item = PrepareItemQuery(context, new()
+        var dbQuery = PrepareItemQuery(context, new()
         {
             DtoOptions = new()
             {
                 EnableImages = true
             }
-        }).FirstOrDefault(e => e.Id == id);
+        });
+        dbQuery = dbQuery.Include(e => e.TrailerTypes)
+            .Include(e => e.Provider)
+            .Include(e => e.LockedFields)
+            .Include(e => e.UserData)
+            .Include(e => e.Images);
+
+        var item = dbQuery.FirstOrDefault(e => e.Id == id);
         if (item is null)
         {
             return null;