zzzprojects / GraphDiff

GraphDiff is a library that allows the automatic update of a detached graph using Entity Framework code first.
https://entityframework-graphdiff.net/overview
MIT License
333 stars 102 forks source link

An item with the same key has already been added #92

Closed BenLewies closed 9 years ago

BenLewies commented 9 years ago

I have the following classes:

I try to update the graph for the Employer root object e using the following code (I have truncated other code to try and isolate the problem):

                db.UpdateGraph(e, map => map                    
                .OwnedEntity(emp => emp.Organisation, with => with
                    .OwnedCollection(org => org.Adresses)
                    .OwnedCollection(org => org.ContactNumbers)));

This throws the following exception:

iisexpress.exe: 0: System.ArgumentException: An item with the same key has already been added. at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource) at System.Collections.Generic.Dictionary2.Insert(TKey key, TValue value, Boolean add) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable1 source, Func2 keySelector) at RefactorThis.GraphDiff.Internal.Graph.CollectionGraphNode.Update[T](IChangeTracker changeTracker, IEntityManager entityManager, T existing, T entity) in c:\***\GraphDiff\GraphDiff\Internal\Graph\CollectionGraphNode.cs:line 27 at RefactorThis.GraphDiff.Internal.Graph.OwnedEntityGraphNode.Update[T](IChangeTracker changeTracker, IEntityManager entityManager, T persisted, T updating) in c:\***\GraphDiff\GraphDiff\Internal\Graph\OwnedEntityGraphNode.cs:line 46 at RefactorThis.GraphDiff.Internal.Graph.GraphNode.Update[T](IChangeTracker changeTracker, IEntityManager entityManager, T persisted, T updating) in c:\***\GraphDiff\GraphDiff\Internal\Graph\GraphNode.cs:line 48 at RefactorThis.GraphDiff.Internal.GraphDiffer1.Merge(T updating, QueryMode queryMode) in c:*\GraphDiff\GraphDiff\Internal\GraphDiffer.cs:line 60 at RefactorThis.GraphDiff.DbContextExtensions.UpdateGraph[T](DbContext context, T entity, Expression`1 mapping, String mappingScheme, UpdateParams updateParams) in c:\GraphDiff\GraphDiff\DbContextExtensions.cs:line 119 at RefactorThis.GraphDiff.DbContextExtensions.UpdateGraph[T](DbContext context, T entity, Expression`1 mapping, UpdateParams updateParams) in c:\**\GraphDiff\GraphDiff\DbContextExtensions.cs:line 32

Additional info

  • As far as I am aware, all entities are in a detached state (AsNoTracking called on all calls to DbContext)
  • There are multiple other entities which are directly / indirectly encapsulated by root which also inherits from Lookup using Table-per-Type inheritance.
BenLewies commented 9 years ago

This error occurred because the root entity did not already exist within the database. Perhaps the UpdateGraph method can be refactored to AddOrUpdate?

ghost commented 9 years ago

I've not yet had a deeper look at the code but UpdateGraph generally supports add-or-update semantics for the root so that shouldn't throw an exception.

EDIT: After inspecting the callstack of your exception I'm quite sure that it's just an actual duplicate. Closing again.

BenLewies commented 9 years ago

Do you perhaps have a link to the original issue?

ghost commented 9 years ago

Sorry, I didn't mean a duplicate issue but a duplicate item added to your context ("An item with the same key has already been added.")... ;)

ghost commented 9 years ago

I just saw your open question regarding this on Stack Overflow. Have you been able to solve this?

BenLewies commented 9 years ago

I basically used a workaround whereby I created and saved an instance of the root object to the database before updating the entire graph. I wasn't able (given current time constraints) to determine why the add-or-update type of functionality is not working with my code.

ghost commented 9 years ago

If you can provide a reproduction I wouldn't mind debugging it and fixing GraphDiff if there's a bug..

BenLewies commented 9 years ago

I'll have to check whether I will be able to do this and get back to you... but thanks Andy.