Eager load metadata for movies

This commit is contained in:
Bogdan 2025-04-12 09:39:23 +03:00
parent 9231a0e526
commit 2b8ca4746a
2 changed files with 32 additions and 36 deletions

View file

@ -25,9 +25,7 @@ public List<ImportListMovie> GetAllForLists(List<int> listIds)
public bool ExistsByMetadataId(int metadataId) public bool ExistsByMetadataId(int metadataId)
{ {
var movies = Query(x => x.MovieMetadataId == metadataId); return Query(x => x.MovieMetadataId == metadataId).Any();
return movies.Any();
} }
} }
} }

View file

@ -61,12 +61,13 @@ protected override IEnumerable<Movie> PagedQuery(SqlBuilder builder) =>
.LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId) .LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId)
.LeftJoin<MovieMetadata, AlternativeTitle>((mm, t) => mm.Id == t.MovieMetadataId); .LeftJoin<MovieMetadata, AlternativeTitle>((mm, t) => mm.Id == t.MovieMetadataId);
private Movie Map(Dictionary<int, Movie> dict, Movie movie, QualityProfile profile, MovieFile movieFile, AlternativeTitle altTitle = null, MovieTranslation translation = null) private Movie Map(Dictionary<int, Movie> dict, Movie movie, MovieMetadata metadata, QualityProfile qualityProfile, MovieFile movieFile, AlternativeTitle altTitle = null, MovieTranslation translation = null)
{ {
if (!dict.TryGetValue(movie.Id, out var movieEntry)) if (!dict.TryGetValue(movie.Id, out var movieEntry))
{ {
movieEntry = movie; movieEntry = movie;
movieEntry.QualityProfile = profile; movieEntry.MovieMetadata = metadata;
movieEntry.QualityProfile = qualityProfile;
movieEntry.MovieFile = movieFile; movieEntry.MovieFile = movieFile;
dict.Add(movieEntry.Id, movieEntry); dict.Add(movieEntry.Id, movieEntry);
} }
@ -88,9 +89,9 @@ protected override List<Movie> Query(SqlBuilder builder)
{ {
var movieDictionary = new Dictionary<int, Movie>(); var movieDictionary = new Dictionary<int, Movie>();
_ = _database.QueryJoined<Movie, QualityProfile, MovieFile, AlternativeTitle>( _ = _database.QueryJoined<Movie, MovieMetadata, QualityProfile, MovieFile, AlternativeTitle>(
builder, builder,
(movie, profile, file, altTitle) => Map(movieDictionary, movie, profile, file, altTitle)); (movie, metadata, qualityProfile, file, altTitle) => Map(movieDictionary, movie, metadata, qualityProfile, file, altTitle));
return movieDictionary.Values.ToList(); return movieDictionary.Values.ToList();
} }
@ -100,23 +101,23 @@ public override IEnumerable<Movie> All()
// the skips the join on profile and alternative title and populates manually // the skips the join on profile and alternative title and populates manually
// to avoid repeatedly deserializing the same profile / movie // to avoid repeatedly deserializing the same profile / movie
var builder = new SqlBuilder(_database.DatabaseType) var builder = new SqlBuilder(_database.DatabaseType)
.LeftJoin<Movie, MovieFile>((m, f) => m.MovieFileId == f.Id) .LeftJoin<Movie, MovieMetadata>((m, f) => m.MovieMetadataId == f.Id)
.LeftJoin<Movie, MovieMetadata>((m, f) => m.MovieMetadataId == f.Id); .LeftJoin<Movie, MovieFile>((m, f) => m.MovieFileId == f.Id);
var profiles = _profileRepository.All().ToDictionary(x => x.Id); var qualityProfiles = _profileRepository.All().ToDictionary(x => x.Id);
var titles = _alternativeTitleRepository.All() var alternativeTitles = _alternativeTitleRepository.All()
.GroupBy(x => x.MovieMetadataId) .GroupBy(x => x.MovieMetadataId)
.ToDictionary(x => x.Key, y => y.ToList()); .ToDictionary(x => x.Key, y => y.ToList());
return _database.QueryJoined<Movie, MovieFile, MovieMetadata>( return _database.QueryJoined<Movie, MovieMetadata, MovieFile>(
builder, builder,
(movie, file, metadata) => (movie, metadata, file) =>
{ {
movie.MovieFile = file;
movie.MovieMetadata = metadata; movie.MovieMetadata = metadata;
movie.QualityProfile = profiles[movie.QualityProfileId]; movie.MovieFile = file;
movie.QualityProfile = qualityProfiles[movie.QualityProfileId];
if (titles.TryGetValue(movie.MovieMetadataId, out var altTitles)) if (alternativeTitles.TryGetValue(movie.MovieMetadataId, out var altTitles))
{ {
movie.MovieMetadata.Value.AlternativeTitles = altTitles; movie.MovieMetadata.Value.AlternativeTitles = altTitles;
} }
@ -155,9 +156,9 @@ private List<Movie> FindByMovieTitles(List<string> titles)
.LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId) .LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId)
.Where<MovieMetadata>(x => titles.Contains(x.CleanTitle) || titles.Contains(x.CleanOriginalTitle)); .Where<MovieMetadata>(x => titles.Contains(x.CleanTitle) || titles.Contains(x.CleanOriginalTitle));
_ = _database.QueryJoined<Movie, QualityProfile, MovieFile>( _ = _database.QueryJoined<Movie, MovieMetadata, QualityProfile, MovieFile>(
builder, builder,
(movie, profile, file) => Map(movieDictionary, movie, profile, file)); (movie, metadata, qualityProfile, file) => Map(movieDictionary, movie, metadata, qualityProfile, file));
return movieDictionary.Values.ToList(); return movieDictionary.Values.ToList();
} }
@ -167,17 +168,17 @@ private List<Movie> FindByAltTitles(List<string> titles)
var movieDictionary = new Dictionary<int, Movie>(); var movieDictionary = new Dictionary<int, Movie>();
var builder = new SqlBuilder(_database.DatabaseType) var builder = new SqlBuilder(_database.DatabaseType)
.Join<AlternativeTitle, MovieMetadata>((t, mm) => t.MovieMetadataId == mm.Id) .Join<AlternativeTitle, MovieMetadata>((t, mm) => t.MovieMetadataId == mm.Id)
.Join<MovieMetadata, Movie>((mm, m) => mm.Id == m.MovieMetadataId) .Join<MovieMetadata, Movie>((mm, m) => mm.Id == m.MovieMetadataId)
.Join<Movie, QualityProfile>((m, p) => m.QualityProfileId == p.Id) .Join<Movie, QualityProfile>((m, p) => m.QualityProfileId == p.Id)
.LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId) .LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId)
.Where<AlternativeTitle>(x => titles.Contains(x.CleanTitle)); .Where<AlternativeTitle>(x => titles.Contains(x.CleanTitle));
_ = _database.QueryJoined<AlternativeTitle, QualityProfile, Movie, MovieFile>( _ = _database.QueryJoined<AlternativeTitle, QualityProfile, Movie, MovieMetadata, MovieFile>(
builder, builder,
(altTitle, profile, movie, file) => (altTitle, qualityProfile, movie, metadata, file) =>
{ {
_ = Map(movieDictionary, movie, profile, file, altTitle); _ = Map(movieDictionary, movie, metadata, qualityProfile, file, altTitle);
return null; return null;
}); });
@ -195,11 +196,11 @@ private List<Movie> FindByTransTitles(List<string> titles)
.LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId) .LeftJoin<Movie, MovieFile>((m, f) => m.Id == f.MovieId)
.Where<MovieTranslation>(x => titles.Contains(x.CleanTitle)); .Where<MovieTranslation>(x => titles.Contains(x.CleanTitle));
_ = _database.QueryJoined<MovieTranslation, QualityProfile, Movie, MovieFile>( _ = _database.QueryJoined<MovieTranslation, QualityProfile, Movie, MovieMetadata, MovieFile>(
builder, builder,
(trans, profile, movie, file) => (trans, qualityProfile, movie, metadata, file) =>
{ {
_ = Map(movieDictionary, movie, profile, file, null, trans); _ = Map(movieDictionary, movie, metadata, qualityProfile, file, null, trans);
return null; return null;
}); });
@ -378,17 +379,14 @@ CROSS JOIN json_each(""MovieMetadata"".""Recommendations"") AS ""j""
public bool ExistsByMetadataId(int metadataId) public bool ExistsByMetadataId(int metadataId)
{ {
var movies = Query(x => x.MovieMetadataId == metadataId); return Query(x => x.MovieMetadataId == metadataId).Any();
return movies.Any();
} }
public HashSet<int> AllMovieWithCollectionsTmdbIds() public HashSet<int> AllMovieWithCollectionsTmdbIds()
{ {
using (var conn = _database.OpenConnection()) using var conn = _database.OpenConnection();
{
return conn.Query<int>("SELECT \"TmdbId\" FROM \"MovieMetadata\" JOIN \"Movies\" ON (\"Movies\".\"MovieMetadataId\" = \"MovieMetadata\".\"Id\") WHERE \"CollectionTmdbId\" > 0").ToHashSet(); return conn.Query<int>("SELECT \"TmdbId\" FROM \"MovieMetadata\" JOIN \"Movies\" ON (\"Movies\".\"MovieMetadataId\" = \"MovieMetadata\".\"Id\") WHERE \"CollectionTmdbId\" > 0").ToHashSet();
}
} }
} }
} }