d6da6906a4
GetBaseItemDtos already batch fetches user data, child counts, played counts and artists before its per item loop, but AttachPeople still ran one GetPeople query per item. Rendering a page of items (for example a large playlist) fired one extra query per row. Add GetPeopleByItems to IPeopleRepository, which reads every requested item in a single query over the people mapping table and returns full PersonInfo (role, type and sort order) grouped by item id. GetBaseItemDtos prefetches this once when the People field is requested and passes it into AttachPeople, which reads from the batch instead of querying per item. The single item GetBaseItemDto path keeps its existing per item behaviour when no batch is supplied. Adds a DtoService test asserting people resolve from the batch and the per item GetPeople is never called.
51 lines
2.1 KiB
C#
51 lines
2.1 KiB
C#
#nullable disable
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using MediaBrowser.Controller.Entities;
|
|
using MediaBrowser.Model.Querying;
|
|
|
|
namespace MediaBrowser.Controller.Persistence;
|
|
|
|
/// <summary>
|
|
/// Provides methods for accessing Peoples.
|
|
/// </summary>
|
|
public interface IPeopleRepository
|
|
{
|
|
/// <summary>
|
|
/// Gets the people.
|
|
/// </summary>
|
|
/// <param name="filter">The query.</param>
|
|
/// <returns>The list of people matching the filter.</returns>
|
|
QueryResult<PersonInfo> GetPeople(InternalPeopleQuery filter);
|
|
|
|
/// <summary>
|
|
/// Updates the people.
|
|
/// </summary>
|
|
/// <param name="itemId">The item identifier.</param>
|
|
/// <param name="people">The people.</param>
|
|
void UpdatePeople(Guid itemId, IReadOnlyList<PersonInfo> people);
|
|
|
|
/// <summary>
|
|
/// Gets the people names.
|
|
/// </summary>
|
|
/// <param name="filter">The query.</param>
|
|
/// <returns>The list of people names matching the filter.</returns>
|
|
IReadOnlyList<string> GetPeopleNames(InternalPeopleQuery filter);
|
|
|
|
/// <summary>
|
|
/// Gets the distinct people names per item for multiple items efficiently by querying from the mapping table.
|
|
/// </summary>
|
|
/// <param name="itemIds">The item IDs to get people for.</param>
|
|
/// <param name="personTypes">The person types to include (e.g. "Actor", "Director").</param>
|
|
/// <returns>A dictionary mapping each item ID to its distinct people names, ordered by cast list order. Items with no matching people are omitted.</returns>
|
|
IReadOnlyDictionary<Guid, IReadOnlyList<string>> GetPeopleNamesByItems(IReadOnlyList<Guid> itemIds, IReadOnlyList<string> personTypes);
|
|
|
|
/// <summary>
|
|
/// Gets the people for multiple items in a single query, keyed by item id.
|
|
/// </summary>
|
|
/// <param name="itemIds">The item IDs to get people for.</param>
|
|
/// <returns>A dictionary mapping each item ID to its people (with role, type and sort order), ordered by cast list order. Items with no people are omitted.</returns>
|
|
IReadOnlyDictionary<Guid, IReadOnlyList<PersonInfo>> GetPeopleByItems(IReadOnlyList<Guid> itemIds);
|
|
}
|