3

When I set db.Entry(episode).State = EntityState.Deleted EF removes episode from my List and throws a collection was modified enumeration operation may not execute.

Here is my code:

public async Task UpdateAsync(List<Episode> episodes)
{
    using (var db = new DbContext())
    {
        var serie = await db.Series.Include(s => s.Episodes).SingleOrDefaultAsync(s => s.Id == id);

        foreach (var episode in serie.Episodes)
        {
            var modifiedEpisode = episodes.Where(e => e.Id == episode.Id).SingleOrDefault();

            //was deleted
            if (modifiedEpisode == null)
            {
                db.Entry(episode).State = EntityState.Deleted;// episode is removed from serie.Episodes throwing exception
                continue;
            }
        }

        var addedEpisodes = episodes.Where(v => v.Id == Guid.Empty).ToList();
        serie.Episodes.AddRange(addedEpisodes);

        await db.SaveChangesAsync();
    }
}

How can I delete episodes?

MuriloKunze
  • 15,195
  • 17
  • 54
  • 82

2 Answers2

7

As Shiraz Bhaiji said, you can't remove an item from a list, while that list is the source of a foreach statement. A simple ToList() could solve your problem

 foreach (var episode in serie.Episodes.ToList())
        {
            var modifiedEpisode = episodes.Where(e => e.Id == episode.Id).SingleOrDefault();

            //was deleted
            if (modifiedEpisode == null)
            {
                db.Entry(episode).State = EntityState.Deleted;// episode is removed from serie.Episodes throwing exception
                continue;
            }
        }

Shiraz Bhaiji's answer is also correct!

Fabio
  • 11,892
  • 1
  • 25
  • 41
  • Episodes is already a List, not a an IEnumerable, so ToList would not work. – MuriloKunze May 25 '15 at 23:19
  • being a list is not the problem... the problem is that your are removing an item from the source of a foreach statement. Take a look at http://stackoverflow.com/questions/604831/collection-was-modified-enumeration-operation-may-not-execute, this guy had the same problm – Fabio May 25 '15 at 23:24
  • I have no ideia why, but calling To List solve the problem(since Episoder is a List). – MuriloKunze May 25 '15 at 23:45
  • 1
    Yes, but when you do ToList you make a "copy" of the items... then you can remove them, since the collection you are removing from is not the same collection you are iterating – Fabio May 26 '15 at 00:12
2

The problem that you are running into is that you cannot change the number of items in a list while looping through the list.

The number of items in the list are changing since you are using the await and async save changes to save changes as they are made.

To fix this simplify your code, remove the await and do a simple save changes when you have finished looping through the list.

Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • The problem is in db.Entry(episode).State = EntityState.Deleted; this line removes one item of my List and cause an exception. – MuriloKunze May 25 '15 at 22:02