-2

I have a work object:

public class Work{
public int WorkId { get; set; }
public virtual Work RelatedWork { get; set; }
public virtual ICollection<Work> RelatedMultipleWorks { get; set; }
}

I'm generating an Work object like this :

Work myWork = new Work();

work mywork2 = new Work();
work mywork3 = new Work();

myWork.RelatedMultipleWorks.add(mywork2);
myWork.RelatedMultipleWorks.add(mywork3);

On DbSaveChanges, I get this exception :

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

What is wrong with the code? How can I fix this? Thanks.

I get the exception at this line :

_db.Works.Add(mywork);

Here is my DbSaveChanges Line :

  _db.Works.Add(_myWork);
  _db.SaveChanges();
  result.Success= true;
  _provider.AddOrUpdate(mywork);

Note : In the actual code, Work entity has a lot more entities. Like hundreds, so I can't post actual code.

EDIT : When I try to add myWork2 or myWork3 using _db.Works.Add(_myWork2);, I still get the same error. Is this error because of a missing entity or something like that?

jason
  • 6,962
  • 36
  • 117
  • 198
  • I suspect that you `Add()` entities that hold references to existing entities (i.e. entities that shouldn't be added). Make sure that you *attach* these existing entities first. – Gert Arnold Dec 27 '16 at 14:28
  • In `Add()` check `context.Entry(item).State == EntityState.Detached` this protect you before duplicating item in current context – M. Wiśnicki Dec 27 '16 at 14:37
  • @M.Wiśnicki I did what you said, but I am still getting the same exception. Do you have any other suggestion? Thanks. – jason Dec 28 '16 at 14:38
  • This error says you are trying to attach an entity to your context but its already attached to another one, can you provide the portion of code where you save your objects to DB `DbSaveChanges` method's – Kevorkian Jan 04 '17 at 14:43
  • @jason This is not the full code... Show how you load the _myWork variable.It's probably loaded from another Context. try to load it like this: _myWork=context.MyWorks.AsNoTracking().Where(...) – George Vovos Jan 04 '17 at 16:34
  • Also,it's 99,% a duplicate of http://stackoverflow.com/questions/10191734/entity-object-cannot-be-referenced-by-multiple-instances-of-ientitychangetracker – George Vovos Jan 04 '17 at 16:39
  • Ok, apparently `_db` is the derived `DbContext`. But what is `_provider` and (why) `_provider.AddOrUpdate(mywork);` call? – Ivan Stoev Jan 04 '17 at 17:19
  • HI Jason, would you mind sharing the structure of table class and explain how work and RelatedMultipleWorks are related in database and also how they are mapped in EF? Also as requested by others here, sharing code snippet of how myWork entitiy is being retrieved and being saved would be very helpful to understand the real issue and solve it. – Chetan Jan 08 '17 at 16:17

4 Answers4

4

Ultimately, this is the same problem mentioned here: How can I use EF to add multiple child entities to an object when the child has an identity key?

If you have a auto generated PK and attempt to do an Add after doing a previous udpate/delete on the same context, it will crash because you end up with the same PKs for multiple objects at the same time.

To fix this, you must either set all those WorkIds (I assume this is the PK) to -1, -2, -3 and their proper FK references to those new numbers
OR
You must add all new entities first before you do any updates/deletes since EF will realize that those IDs will be set in the future.

Giulio Caccin
  • 2,962
  • 6
  • 36
  • 57
Daniel Lorenz
  • 4,178
  • 1
  • 32
  • 39
  • **you must either set all those WorkIds (I assume this is the PK) to -1, -2, -3 and their proper FK references to those new numbers** I don't know how to change FK references, can you please elaborate that part? Thanks. – jason Jan 05 '17 at 11:12
  • By the way I tried your second solution, but when I try to add all entities first, it didn't work either. It again gave the same error. – jason Jan 05 '17 at 11:14
  • Sure. Though, hmm... Don't you have a ParentWorkId or something? How are RelatedMultipleWorks tied back to the parent? That could be a problem, but EF should have thrown a run-time exception if that were the case. Ultimately, if you don't set the WorkId, all 3 will have a WorkId of 0. It would then think they were referencing the same object since they all had the same PK. Another approach would be to create and save each record individually before hooking them up. – Daniel Lorenz Jan 06 '17 at 14:33
1

The problem exists here actually:

Work myWork = new Work();    
work mywork2 = new Work();
work mywork3 = new Work();

You are creating a data context in the public constructor of each class as this must be what is building the work class, you are then trying to add it and build multiple relations to each objects in your collection using multiple contexts instantiated of the same Entity object. This is the complaint. The fix is to create a new constructor that takes a context that was created outside of the classes and use it as a parameter to instantiate each class. They should look like this:

work myWork = new Work(mySingleContext);
work myWork2 = new Work(mySingleContext);
work myWork3 = new Work(mySingleContext);

This should satisfy the requirements, however be aware that if you are doing the same thing with other items and adding a context to another item instantiated from the same Entity item you will still error. However, now when you call the .Add() method the items will be sharing the same Entity instance and the error should not be raised.

0

Add tags to your object on the ID property

 [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
 [Key]
Keith
  • 1,119
  • 2
  • 12
  • 23
-1

Maybe you could try:

myWork.RelatedMultipleWorks.addRange(new List<Work>{ mywork1, mywork2 });

Second try on this one:

What happens if you remove the virtual keyword from the RelatedMultipleWorks member of the Work object?

Third run:

WorkId is the primary key? Maybe it needs a value?

Also seems like the child objects would need to be added to the database first - the primary key is a reference to an existing object.

John Meyer
  • 2,296
  • 1
  • 31
  • 39