diff --git a/ApplicationServices/LibraryCommands.cs b/ApplicationServices/LibraryCommands.cs index cc233231..50af6fa2 100644 --- a/ApplicationServices/LibraryCommands.cs +++ b/ApplicationServices/LibraryCommands.cs @@ -104,8 +104,11 @@ namespace ApplicationServices { try { - book.UserDefinedItem.Tags = newTags; + var udi = book.UserDefinedItem; + // Attach() NoTracking entities before SaveChanges() + udi.Tags = newTags; + context.Attach(udi).State = Microsoft.EntityFrameworkCore.EntityState.Modified; var qtyChanges = context.SaveChanges(); if (qtyChanges > 0) diff --git a/DataLayer/QueryObjects/BookQueries.cs b/DataLayer/QueryObjects/BookQueries.cs index d4a83263..c6fa3098 100644 --- a/DataLayer/QueryObjects/BookQueries.cs +++ b/DataLayer/QueryObjects/BookQueries.cs @@ -11,7 +11,7 @@ namespace DataLayer public static Book GetBook_Flat_NoTracking(this LibationContext context, string productId) => context .Books - .AsNoTracking() + .AsNoTrackingWithIdentityResolution() .GetBook(productId); public static Book GetBook(this IQueryable books, string productId) diff --git a/DataLayer/QueryObjects/LibraryQueries.cs b/DataLayer/QueryObjects/LibraryQueries.cs index 790a1d8d..fb366c32 100644 --- a/DataLayer/QueryObjects/LibraryQueries.cs +++ b/DataLayer/QueryObjects/LibraryQueries.cs @@ -6,25 +6,31 @@ namespace DataLayer { public static class LibraryQueries { - public static List GetLibrary_Flat_WithTracking(this LibationContext context) - => context - .Library - .GetLibrary() - .ToList(); + //// tracking is a bad idea for main grid. it prevents anything else from updating entities unless getting them from the grid + //public static List GetLibrary_Flat_WithTracking(this LibationContext context) + // => context + // .Library + // .GetLibrary() + // .ToList(); public static List GetLibrary_Flat_NoTracking(this LibationContext context) => context .Library - .AsNoTracking() + .AsNoTrackingWithIdentityResolution() .GetLibrary() .ToList(); public static LibraryBook GetLibraryBook_Flat_NoTracking(this LibationContext context, string productId) => context .Library - .AsNoTracking() + .AsNoTrackingWithIdentityResolution() .GetLibraryBook(productId); + public static LibraryBook GetLibraryBook(this IQueryable library, string productId) + => library + .GetLibrary() + .SingleOrDefault(lb => lb.Book.AudibleProductId == productId); + /// This is still IQueryable. YOU MUST CALL ToList() YOURSELF public static IQueryable GetLibrary(this IQueryable library) => library @@ -32,10 +38,5 @@ namespace DataLayer .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 LibraryBook GetLibraryBook(this IQueryable library, string productId) - => library - .GetLibrary() - .SingleOrDefault(le => le.Book.AudibleProductId == productId); } } diff --git a/FileLiberator/DownloadFile.cs b/FileLiberator/DownloadFile.cs index fd01183f..13f38479 100644 --- a/FileLiberator/DownloadFile.cs +++ b/FileLiberator/DownloadFile.cs @@ -5,7 +5,6 @@ using Dinah.Core.Net.Http; namespace FileLiberator { - // frustratingly copy pasta from DownloadableBase and DownloadPdf // currently only used to download the .zip flies for upgrade public class DownloadFile : IDownloadable { diff --git a/FileLiberator/DownloadPdf.cs b/FileLiberator/DownloadPdf.cs index ceab5ff6..d16c86d5 100644 --- a/FileLiberator/DownloadPdf.cs +++ b/FileLiberator/DownloadPdf.cs @@ -22,11 +22,6 @@ namespace FileLiberator return verifyDownload(libraryBook); } - private static StatusHandler verifyDownload(LibraryBook libraryBook) - => !AudibleFileStorage.PDF.Exists(libraryBook.Book.AudibleProductId) - ? new StatusHandler { "Downloaded PDF cannot be found" } - : new StatusHandler(); - private static string getProposedDownloadFilePath(LibraryBook libraryBook) { // if audio file exists, get it's dir. else return base Book dir @@ -44,6 +39,9 @@ namespace FileLiberator return full; } + private static string getdownloadUrl(LibraryBook libraryBook) + => libraryBook?.Book?.Supplements?.FirstOrDefault()?.Url; + private async Task downloadPdfAsync(LibraryBook libraryBook, string proposedDownloadFilePath) { var api = await GetApiAsync(libraryBook); @@ -55,7 +53,9 @@ namespace FileLiberator (p) => client.DownloadFileAsync(downloadUrl, proposedDownloadFilePath, p)); } - private static string getdownloadUrl(LibraryBook libraryBook) - => libraryBook?.Book?.Supplements?.FirstOrDefault()?.Url; + private static StatusHandler verifyDownload(LibraryBook libraryBook) + => !AudibleFileStorage.PDF.Exists(libraryBook.Book.AudibleProductId) + ? new StatusHandler { "Downloaded PDF cannot be found" } + : new StatusHandler(); } } diff --git a/FileLiberator/IProcessableExt.cs b/FileLiberator/IProcessableExt.cs index ef7bed21..d5e46596 100644 --- a/FileLiberator/IProcessableExt.cs +++ b/FileLiberator/IProcessableExt.cs @@ -25,10 +25,7 @@ namespace FileLiberator public static LibraryBook GetSingleLibraryBook(string productId) { using var context = DbContexts.GetContext(); - var libraryBook = context - .Library - .GetLibrary() - .SingleOrDefault(lb => lb.Book.AudibleProductId == productId); + var libraryBook = context.GetLibraryBook_Flat_NoTracking(productId); return libraryBook; } diff --git a/FileManager/TagsPersistence.cs b/FileManager/TagsPersistence.cs index 57d6f9fc..5ae19e37 100644 --- a/FileManager/TagsPersistence.cs +++ b/FileManager/TagsPersistence.cs @@ -31,6 +31,9 @@ namespace FileManager { ensureCache(); + if (!tagsCollection.Any()) + return; + // on initial reload, there's a huge benefit to adding to cache individually then updating the file only once foreach ((string productId, string tags) in tagsCollection) cache[productId] = tags; diff --git a/LibationLauncher/LibationLauncher.csproj b/LibationLauncher/LibationLauncher.csproj index 778cf71e..f70b4c91 100644 --- a/LibationLauncher/LibationLauncher.csproj +++ b/LibationLauncher/LibationLauncher.csproj @@ -13,7 +13,7 @@ win-x64 - 5.4.1.5 + 5.4.2.1 diff --git a/LibationWinForms/ProductsGrid.cs b/LibationWinForms/ProductsGrid.cs index b5d55891..89e27cbe 100644 --- a/LibationWinForms/ProductsGrid.cs +++ b/LibationWinForms/ProductsGrid.cs @@ -338,7 +338,7 @@ namespace LibationWinForms // transform into sorted GridEntry.s BEFORE binding // context = DbContexts.GetContext(); - var lib = context.GetLibrary_Flat_WithTracking(); + var lib = context.GetLibrary_Flat_NoTracking(); // if no data. hide all columns. return if (!lib.Any())