102 lines
4.5 KiB
C#
102 lines
4.5 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace DataLayer
|
|
{
|
|
// only library importing should use tracking. All else should be NoTracking.
|
|
// only library importing should directly query Book. All else should use LibraryBook
|
|
public static class LibraryBookQueries
|
|
{
|
|
//// tracking is a bad idea for main grid. it prevents anything else from updating entities unless getting them from the grid
|
|
//public static List<LibraryBook> GetLibrary_Flat_WithTracking(this LibationContext context)
|
|
// => context
|
|
// .Library
|
|
// .GetLibrary()
|
|
// .ToList();
|
|
|
|
public static List<LibraryBook> GetLibrary_Flat_NoTracking(this LibationContext context, bool includeParents = false)
|
|
=> context
|
|
.LibraryBooks
|
|
.AsNoTrackingWithIdentityResolution()
|
|
.GetLibrary()
|
|
.AsEnumerable()
|
|
.Where(lb => !lb.Book.IsEpisodeParent() || includeParents)
|
|
.ToList();
|
|
|
|
public static LibraryBook GetLibraryBook_Flat_NoTracking(this LibationContext context, string productId)
|
|
=> context
|
|
.LibraryBooks
|
|
.AsNoTrackingWithIdentityResolution()
|
|
.GetLibraryBook(productId);
|
|
|
|
public static LibraryBook GetLibraryBook(this IQueryable<LibraryBook> library, string productId)
|
|
=> library
|
|
.GetLibrary()
|
|
.SingleOrDefault(lb => lb.Book.AudibleProductId == productId);
|
|
|
|
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
|
|
public static IQueryable<LibraryBook> GetLibrary(this IQueryable<LibraryBook> library)
|
|
=> library
|
|
.Where(lb => !lb.IsDeleted)
|
|
// owned items are always loaded. eg: book.UserDefinedItem, book.Supplements
|
|
.Include(le => le.Book).ThenInclude(b => b.SeriesLink).ThenInclude(sb => sb.Series)
|
|
.Include(le => le.Book).ThenInclude(b => b.ContributorsLink).ThenInclude(c => c.Contributor)
|
|
.Include(le => le.Book).ThenInclude(b => b.Category).ThenInclude(c => c.ParentCategory);
|
|
|
|
public static IEnumerable<LibraryBook> ParentedEpisodes(this IEnumerable<LibraryBook> libraryBooks)
|
|
=> libraryBooks.Where(lb => lb.Book.IsEpisodeParent()).SelectMany(libraryBooks.FindChildren);
|
|
|
|
public static IEnumerable<LibraryBook> FindOrphanedEpisodes(this IEnumerable<LibraryBook> libraryBooks)
|
|
=> libraryBooks
|
|
.Where(lb => lb.Book.IsEpisodeChild())
|
|
.ExceptBy(
|
|
libraryBooks
|
|
.ParentedEpisodes()
|
|
.Select(ge => ge.Book.AudibleProductId), ge => ge.Book.AudibleProductId);
|
|
|
|
#nullable enable
|
|
public static LibraryBook? FindSeriesParent(this IEnumerable<LibraryBook> libraryBooks, LibraryBook seriesEpisode)
|
|
{
|
|
if (seriesEpisode.Book.SeriesLink is null) return null;
|
|
|
|
try
|
|
{
|
|
//Parent books will always have exactly 1 SeriesBook due to how
|
|
//they are imported in ApiExtended.getChildEpisodesAsync()
|
|
return libraryBooks.FirstOrDefault(
|
|
lb =>
|
|
lb.Book.IsEpisodeParent() &&
|
|
seriesEpisode.Book.SeriesLink.Any(
|
|
s => s.Series.AudibleSeriesId == lb.Book.SeriesLink.Single().Series.AudibleSeriesId));
|
|
}
|
|
catch (System.Exception ex)
|
|
{
|
|
Serilog.Log.Error(ex, "Query error in {0}", nameof(FindSeriesParent));
|
|
return null;
|
|
}
|
|
}
|
|
#nullable disable
|
|
|
|
public static IEnumerable<LibraryBook> FindChildren(this IEnumerable<LibraryBook> bookList, LibraryBook parent)
|
|
=> bookList
|
|
.Where(
|
|
lb =>
|
|
lb.Book.IsEpisodeChild() &&
|
|
lb.Book.SeriesLink?
|
|
.Any(
|
|
s =>
|
|
s.Series.AudibleSeriesId == parent.Book.AudibleProductId
|
|
) == true
|
|
).ToList();
|
|
|
|
public static IEnumerable<LibraryBook> UnLiberated(this IEnumerable<LibraryBook> bookList)
|
|
=> bookList
|
|
.Where(
|
|
lb =>
|
|
lb.Book.UserDefinedItem.BookStatus is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload
|
|
|| lb.Book.UserDefinedItem.PdfStatus is LiberatedStatus.NotLiberated or LiberatedStatus.PartialDownload
|
|
);
|
|
}
|
|
}
|