Michael Bucari-Tovo 2d6120f0c4 Get full library in LibrarySizeChanged event and pass as EventArgs
There are multiple subscribers to LibraryCommands.LibrarySizeChanged, and each one calls GetLibrary_Flat_NoTracking(). Passing the full library as an event argument speeds up all operations which happen after the library size changes.

Fix initial backup counts
2025-02-27 13:11:28 -07:00

56 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
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 BookQueries
{
public static Book GetBook_Flat_NoTracking(this LibationContext context, string productId)
=> context
.Books
.AsNoTrackingWithIdentityResolution()
.GetBook(productId);
public static Book GetBook(this IQueryable<Book> books, string productId)
=> books
.GetBooks()
// 'Single' is more accurate but 'First' is faster and less error prone
.FirstOrDefault(b => b.AudibleProductId == productId);
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
public static IQueryable<Book> GetBooks(this IQueryable<Book> books, Expression<Func<Book, bool>> predicate)
=> books
.GetBooks()
.Where(predicate);
/// <summary>This is still IQueryable. YOU MUST CALL ToList() YOURSELF</summary>
public static IQueryable<Book> GetBooks(this IQueryable<Book> books)
=> books
// owned items are always loaded. eg: book.UserDefinedItem, book.Supplements
.Include(b => b.SeriesLink).ThenInclude(sb => sb.Series)
.Include(b => b.ContributorsLink).ThenInclude(c => c.Contributor)
.Include(b => b.CategoriesLink).ThenInclude(c => c.CategoryLadder).ThenInclude(c => c._categories);
public static bool IsProduct(this Book book)
=> book.ContentType is not ContentType.Episode and not ContentType.Parent;
public static bool IsEpisodeChild(this Book book)
=> book.ContentType is ContentType.Episode;
public static bool IsEpisodeParent(this Book book)
=> book.ContentType is ContentType.Parent;
public static IEnumerable<LibraryBook> WithoutParents(this IEnumerable<LibraryBook> libraryBooks)
=> libraryBooks.Where(lb => !lb.Book.IsEpisodeParent());
public static bool HasLiberated(this Book book)
=> book.UserDefinedItem.BookStatus is LiberatedStatus.Liberated ||
book.UserDefinedItem.PdfStatus is not null and LiberatedStatus.Liberated;
}
}