From 6c5773df24502f23a305b95544e7c9d74dce1ae9 Mon Sep 17 00:00:00 2001 From: Michael Bucari-Tovo Date: Wed, 26 Feb 2025 14:41:59 -0700 Subject: [PATCH] Fix stack overflow exception when updating large databases (#1158) --- Source/ApplicationServices/LibraryCommands.cs | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Source/ApplicationServices/LibraryCommands.cs b/Source/ApplicationServices/LibraryCommands.cs index 8e56e9b3..71ed011e 100644 --- a/Source/ApplicationServices/LibraryCommands.cs +++ b/Source/ApplicationServices/LibraryCommands.cs @@ -369,12 +369,12 @@ namespace ApplicationServices using var context = DbContexts.GetContext(); - // Attach() NoTracking entities before SaveChanges() - foreach (var lb in removeLibraryBooks) + // Entry() NoTracking entities before SaveChanges() + foreach (var lb in removeLibraryBooks) { - lb.IsDeleted = true; - context.Attach(lb).State = Microsoft.EntityFrameworkCore.EntityState.Modified; - } + lb.IsDeleted = true; + context.Entry(lb).State = Microsoft.EntityFrameworkCore.EntityState.Modified; + } var qtyChanges = context.SaveChanges(); if (qtyChanges > 0) @@ -398,12 +398,12 @@ namespace ApplicationServices using var context = DbContexts.GetContext(); - // Attach() NoTracking entities before SaveChanges() - foreach (var lb in libraryBooks) - { - lb.IsDeleted = false; - context.Attach(lb).State = Microsoft.EntityFrameworkCore.EntityState.Modified; - } + // Entry() NoTracking entities before SaveChanges() + foreach (var lb in libraryBooks) + { + lb.IsDeleted = false; + context.Entry(lb).State = Microsoft.EntityFrameworkCore.EntityState.Modified; + } var qtyChanges = context.SaveChanges(); if (qtyChanges > 0) @@ -518,17 +518,18 @@ namespace ApplicationServices if (libraryBooks is null || !libraryBooks.Any()) return 0; - foreach (var book in libraryBooks) - action?.Invoke(book.Book.UserDefinedItem); - using var context = DbContexts.GetContext(); - // Attach() NoTracking entities before SaveChanges() - foreach (var book in libraryBooks) + // Entry() instead of Attach() due to possible stack overflow with large tables + foreach (var book in libraryBooks) { - context.Attach(book.Book.UserDefinedItem).State = Microsoft.EntityFrameworkCore.EntityState.Modified; - context.Attach(book.Book.UserDefinedItem.Rating).State = Microsoft.EntityFrameworkCore.EntityState.Modified; - } + action?.Invoke(book.Book.UserDefinedItem); + + var udiEntity = context.Entry(book.Book.UserDefinedItem); + + udiEntity.State = Microsoft.EntityFrameworkCore.EntityState.Modified; + udiEntity.Reference(udi => udi.Rating).TargetEntry.State = Microsoft.EntityFrameworkCore.EntityState.Modified; + } var qtyChanges = context.SaveChanges(); if (qtyChanges > 0)