EFCore/C# – Collection Modified -> Operation may not execute

I have the following loop. As soon as the first iteration succeeds, I get the following error: enter image description here

In no place inside the for loop I am changing either weeklyReportsList or weeklyReport1.DailyReports, so I don’t understand where the error is coming from, I can’t seem to find the location where the Collection might be modified

Code

foreach (var weeklyReport1 in weeklyReportsList)
            {
                foreach(var dailyReport in weeklyReport1.DailyReports)
                {
                    _context.Attach(dailyReport);

                    User user = GetDataUser(Convert.ToInt32(User.FindFirst(ClaimTypes.PrimarySid).Value));

                    if (user == null)
                    {
                        _toastNotification.AddErrorToastMessage("Utilizador não encontrado.");
                        OnGet();
                        return Page();
                    }
                    else
                    {
                        dailyReport.UserCreator = user;
                    }

                    /*dailyReport.States = GetDataStates(state);
                    _context.Entry(dailyReport).Reference(dr => dr.States).IsModified = true;*/

                    dailyReport.EstimatedDate = nextDate;
                    _context.Entry(dailyReport).Property(dr => dr.EstimatedDate).IsModified = true;

                    dailyReport.WeeklyReportId = nextWeeklyReport.Id;
                    dailyReport.WeekDay = GetWeekDayName((DateTime)dailyReport.EstimatedDate);

                    try
                    {
                        await _context.SaveChangesAsync();
                    }
                    catch (DbUpdateException e)
                    {
                        _toastNotification.AddErrorToastMessage("Falha ao editar Registo");
                        Console.Write(e);
                        return RedirectToPage("Index");
                    }

                    _context.Entry(dailyReport).State = EntityState.Detached;
                    await CreateLog(dailyReport.Id);
                }
            }

public async Task<IActionResult> CreateLog(int id)
        {
            DailyReport editedDailyReport = GetDailyReport(id);
            User user = GetDataUser(Convert.ToInt32(User.FindFirst(ClaimTypes.PrimarySid).Value));
            LogReports logReports = new LogReports(editedDailyReport, "Edição Registo Atrasado", user.Id);
            _context.LogReportsReception.Add(logReports);

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateException e)
            {
                Console.Write(e);
                _toastNotification.AddWarningToastMessage("Log Registo não criado");
            }
            return null;
        }

PS: All other functions (Get...()) are data retrieval related only. No attributions whatsoever there

Answer

The collection that you iterate with foreach may not be modified during iteration. So, you cannot modify the elements in this way. You can however loop through a copy of the collection. For instance Collection.ToList() at the loop instantiation. This will let you modify your actual collection in the loop while not altering the “Copy” of the Collection. You can verify this by changing:

foreach(var dailyReport in weeklyReport1.DailyReports)

To

foreach(var dailyReport in weeklyReport1.DailyReports.ToList())

Leave a Reply

Your email address will not be published. Required fields are marked *