Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InvalidOperationException: "Collection was modified" inside NavigationFixer #8101

Closed
joshmouch opened this issue Apr 7, 2017 · 0 comments
Closed
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@joshmouch
Copy link

joshmouch commented Apr 7, 2017

I have some code that is adding an entity to the DbContext if it hasn't previously been added. This works in most cases, however, in one case I've found, there's an exception being throw in the ChangeTracking.Internal.NavigationFixer.

The code is:

public void Add<TEntity>(TEntity entity) where TEntity : class
		{
			var entry = this.DataContext.Entry(entity);
			if (entry.State == EntityState.Detached)
			{
				this.DataContext.Add((object)entity);
			}
		}

The exact exception is:

System.InvalidOperationException occurred
  HResult=0x80131509
  Message=Collection was modified; enumeration operation may not execute.
  Source=System.Core
  StackTrace:
   at System.Collections.Generic.HashSet`1.Enumerator.MoveNext()
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(InternalEntityEntry entry, ISet`1 handledForeignKeys, Boolean fromQuery)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.StateChanged(InternalEntityEntry entry, EntityState oldState, Boolean fromQuery)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState entityState, Boolean acceptChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(EntityEntryGraphNode node)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph(EntityEntryGraphNode node, Func`2 handleNode)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(InternalEntityEntry rootEntry, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(InternalEntityEntry entry, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.SetEntityState(Object entity, EntityState entityState)
   at Microsoft.EntityFrameworkCore.DbContext.Add(Object entity)

The stack trace is:

 	System.Core.dll!System.Collections.Generic.HashSet<MyEntity>.Enumerator.MoveNext()	Unknown
>	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.InitialFixup(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, System.Collections.Generic.ISet<Microsoft.EntityFrameworkCore.Metadata.IForeignKey> handledForeignKeys, bool fromQuery)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.NavigationFixer.StateChanged(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, Microsoft.EntityFrameworkCore.EntityState oldState, bool fromQuery)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryNotifier.StateChanged(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, Microsoft.EntityFrameworkCore.EntityState oldState, bool fromQuery)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(Microsoft.EntityFrameworkCore.EntityState oldState, Microsoft.EntityFrameworkCore.EntityState newState, bool acceptChanges)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(Microsoft.EntityFrameworkCore.EntityState entityState, bool acceptChanges)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.PaintAction(Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntryGraphNode node)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityEntryGraphIterator.TraverseGraph(Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntryGraphNode node, System.Func<Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntryGraphNode, bool> handleNode)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.ChangeTracking.Internal.EntityGraphAttacher.AttachGraph(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry rootEntry, Microsoft.EntityFrameworkCore.EntityState entityState)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.DbContext.SetEntityState(Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry entry, Microsoft.EntityFrameworkCore.EntityState entityState)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.DbContext.SetEntityState(object entity, Microsoft.EntityFrameworkCore.EntityState entityState)	Unknown
 	Microsoft.EntityFrameworkCore.dll!Microsoft.EntityFrameworkCore.DbContext.Add(object entity)	Unknown

I went through the source code in that class and I only see some "foreach" loops, but I'm not immediately aware of anything I may be doing to affect these Enumerables.

I'm still investigating.

The only thing of note so far is that the TEntity type in the HashSet in the stack trace is a child collection of the TEntity type passed into the Add method in the first code snippet.

@ajcvickers ajcvickers self-assigned this Apr 7, 2017
@ajcvickers ajcvickers added this to the 2.0.0 milestone Apr 7, 2017
@ajcvickers ajcvickers modified the milestones: 2.0.0-preview1, 2.0.0 Apr 19, 2017
ajcvickers added a commit that referenced this issue Jun 23, 2017
Issue #8101

Happens when entities are inconsistently fixed up and do shenanigans in setters. (May also happen in other scenarios, but I was able to repro it this way.) Fix is to do defensive copy.
ajcvickers added a commit that referenced this issue Jun 26, 2017
Issue #8101

Happens when entities are inconsistently fixed up and do shenanigans in setters. (May also happen in other scenarios, but I was able to repro it this way.) Fix is to do defensive copy.
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jun 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

2 participants