< Summary - Jellyfin

Information
Class: Jellyfin.Database.Implementations.ModelConfiguration.BaseItemConfiguration
Assembly: Jellyfin.Database.Implementations
File(s): /srv/git/jellyfin/src/Jellyfin.Database/Jellyfin.Database.Implementations/ModelConfiguration/BaseItemConfiguration.cs
Line coverage
100%
Covered lines: 51
Uncovered lines: 0
Coverable lines: 51
Total lines: 94
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/16/2026 - 12:15:55 AM Line coverage: 100% (47/47) Total lines: 877/27/2026 - 12:16:14 AM Line coverage: 100% (49/49) Total lines: 9210/29/2026 - 12:17:11 AM Line coverage: 100% (51/51) Total lines: 94

Coverage delta

Coverage delta 1 -1

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Configure(...)100%11100%

File(s)

/srv/git/jellyfin/src/Jellyfin.Database/Jellyfin.Database.Implementations/ModelConfiguration/BaseItemConfiguration.cs

#LineLine coverage
 1using System;
 2using Jellyfin.Database.Implementations.Entities;
 3using Microsoft.EntityFrameworkCore;
 4using Microsoft.EntityFrameworkCore.Metadata.Builders;
 5
 6namespace Jellyfin.Database.Implementations.ModelConfiguration;
 7
 8/// <summary>
 9/// Configuration for BaseItem.
 10/// </summary>
 11public class BaseItemConfiguration : IEntityTypeConfiguration<BaseItemEntity>
 12{
 13    /// <inheritdoc/>
 14    public void Configure(EntityTypeBuilder<BaseItemEntity> builder)
 15    {
 416        builder.HasKey(e => e.Id);
 17        // TODO: See rant in entity file.
 18        // builder.HasOne(e => e.Parent).WithMany(e => e.DirectChildren).HasForeignKey(e => e.ParentId);
 19        // builder.HasOne(e => e.TopParent).WithMany(e => e.AllChildren).HasForeignKey(e => e.TopParentId);
 20        // builder.HasOne(e => e.Season).WithMany(e => e.SeasonEpisodes).HasForeignKey(e => e.SeasonId);
 21        // builder.HasOne(e => e.Series).WithMany(e => e.SeriesEpisodes).HasForeignKey(e => e.SeriesId);
 422        builder.HasMany(e => e.Peoples);
 423        builder.HasMany(e => e.UserData);
 424        builder.HasMany(e => e.ItemValues);
 425        builder.HasMany(e => e.MediaStreams);
 426        builder.HasMany(e => e.Chapters);
 427        builder.HasMany(e => e.Provider);
 428        builder.HasMany(e => e.Parents);
 429        builder.HasMany(e => e.Children);
 430        builder.HasMany(e => e.DirectChildren).WithOne(e => e.DirectParent).HasForeignKey(e => e.ParentId).OnDelete(Dele
 431        builder.HasMany(e => e.Extras).WithOne(e => e.Owner).HasForeignKey(e => e.OwnerId).OnDelete(DeleteBehavior.NoAct
 432        builder.HasMany(e => e.LockedFields);
 433        builder.HasMany(e => e.TrailerTypes);
 434        builder.HasMany(e => e.Images);
 35
 436        builder.HasIndex(e => e.Path);
 437        builder.HasIndex(e => e.ParentId);
 438        builder.HasIndex(e => e.OwnerId)
 439            .HasFilter("\"OwnerId\" IS NOT NULL");
 440        builder.HasIndex(e => e.Name);
 441        builder.HasIndex(e => new { e.ExtraType, e.OwnerId })
 442            .HasFilter("\"ExtraType\" IS NOT NULL");
 443        builder.HasIndex(e => e.PresentationUniqueKey);
 44        // covering index
 445        builder.HasIndex(e => new { e.TopParentId, e.Id });
 46        // series
 447        builder.HasIndex(e => new { e.Type, e.SeriesPresentationUniqueKey, e.PresentationUniqueKey, e.SortName });
 48        // series counts
 49        // seriesdateplayed sort order
 450        builder.HasIndex(e => new { e.Type, e.SeriesPresentationUniqueKey, e.IsFolder, e.IsVirtualItem });
 51        // live tv programs
 452        builder.HasIndex(e => new { e.Type, e.TopParentId, e.StartDate });
 53        // covering index for getitemvalues
 454        builder.HasIndex(e => new { e.Type, e.TopParentId, e.Id });
 55        // used by movie suggestions
 456        builder.HasIndex(e => new { e.Type, e.TopParentId, e.PresentationUniqueKey });
 57        // latest items
 458        builder.HasIndex(e => new { e.Type, e.TopParentId, e.IsVirtualItem, e.PresentationUniqueKey, e.DateCreated });
 459        builder.HasIndex(e => new { e.IsFolder, e.TopParentId, e.IsVirtualItem, e.PresentationUniqueKey, e.DateCreated }
 60        // latest items - optimized for sorting by DateCreated (no PresentationUniqueKey breaking the sort)
 461        builder.HasIndex(e => new { e.TopParentId, e.Type, e.IsVirtualItem, e.DateCreated });
 462        builder.HasIndex(e => new { e.TopParentId, e.IsFolder, e.IsVirtualItem, e.DateCreated });
 463        builder.HasIndex(e => new { e.TopParentId, e.MediaType, e.IsVirtualItem, e.DateCreated });
 64        // resume
 465        builder.HasIndex(e => new { e.MediaType, e.TopParentId, e.IsVirtualItem, e.PresentationUniqueKey });
 66        // alternate versions of an item, e.g. resolving the played date of a version onto its primary.
 67        // Filtered: almost no item has a primary version, and an index covering those rows too would tempt
 68        // the planner into serving "PrimaryVersionId IS NULL" - true for the whole library - out of it.
 469        builder.HasIndex(e => e.PrimaryVersionId)
 470            .HasFilter("\"PrimaryVersionId\" IS NOT NULL");
 71        // sorted library queries (e.g., Series sorted by SortName)
 472        builder.HasIndex(e => new { e.Type, e.TopParentId, e.SortName });
 73        // NextUp: per-series episode ordering (index seek + range scan on season/episode)
 474        builder.HasIndex(e => new { e.Type, e.SeriesPresentationUniqueKey, e.ParentIndexNumber, e.IndexNumber });
 75        // ByName queries: WHERE Type = X AND CleanName IN (...)
 476        builder.HasIndex(e => new { e.Type, e.CleanName });
 77        // Latest TV: GROUP BY SeriesName
 478        builder.HasIndex(e => e.SeriesName);
 79        // Latest TV: episode count per season, season count per series
 480        builder.HasIndex(e => e.SeasonId);
 481        builder.HasIndex(e => e.SeriesId);
 82
 83        // Items/Counts: SELECT Type, COUNT(*) GROUP BY Type filtered by TopParentId.
 484        builder.HasIndex(e => new { e.TopParentId, e.Type, e.IsVirtualItem })
 485            .HasFilter("\"PrimaryVersionId\" IS NULL AND (\"OwnerId\" IS NULL OR \"ExtraType\" IS NOT NULL)");
 86
 487        builder.HasData(new BaseItemEntity()
 488        {
 489            Id = Guid.Parse("00000000-0000-0000-0000-000000000001"),
 490            Type = "PLACEHOLDER",
 491            Name = "This is a placeholder item for UserData that has been detached from its original item",
 492        });
 493    }
 94}