So I am trying to Delete some items from the database before I Insert some data. For some reason, C# Entity Framework and ASP.NET do not enjoy me doing this simple operation and gives out another one of those vague errors.
I am trying to update a set of rows of information in a table (using foreach loops and Insert/Delete), as well as some properties in another table (using update)
How do I fix it? The error occurs on the Delete function, on the line: this.entities.tableModule.Attach(module);
I get: "System.InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker."
public void Insert(tableModule module)
{
this.entities.tableModule.AddObject(module);
this.entities.SaveChanges();
}
public void Delete(tableModule module)
{
this.entities.tableModule.Attach(module); // error HERE
this.entities.DeleteObject(module);
this.entities.SaveChanges();
}
Further down the code I call Delete and Insert and Update for another table.
try
{
DifferentClass.Update(tu);
foreach (tableModule mitem in list_to_del)
{
moduleclass.Delete(mitem); // remove all super roles by the user.
}
foreach (tableModule m_to_add in add_list)
{
moduleclass.Insert(m_to_add);
}
}
From what I gather, the attach function is maybe being run more than once and that for some reason is something that the designers of C# Entity Framework are completely caught by surprise for, and so they produce an error. Though it's most likely my complete lack of understanding of entity framework.
EDIT: Here's how I get the list_to_del array.
List<tableModule> list_to_del = (from m in entities.tableModule where m.userid == (long)userID select m).ToList();
EDIT2:
New test code:
public void InsertQueue(tableModule module)
{
this.entities.tableModule.AddObject(module);
}
public void DeleteQueue(tableModule module)
{
this.entities.tableModule.Attach(module);
this.entities.DeleteObject(module);
}
public void FinallySave(){
this.entities.SaveChanges();
}
EDIT 3 ---- SOLUTION -----
The test code worked sort of (though inserts didn't for some odd reason). The problem was, I was calling list_to_del query to get that array of tableModules from a tableUser class which has its own entityset/context. So the results in list_to_del were of a different context, than the call to the class that does DeleteQueue / Insert etc.
I changed:
List<tableModule> list_to_del = (from m in entities.tableModule where m.userid == (long)userID select m).ToList();
to the appropriate class that has the SAME query:
List<tableModule> list_to_del = ModuleClass.GetListofModulesByUserID(userID);
Of course ModuleClass.InsertQueue and ModuleClass.DeleteQueue is called.
So everything uses the same entities object (context/entityset).
So the error happens when you call a query on a context, that returns a set of results that are ALREADY attached to that context. Then when you call Attach again, a problem occurs because they already are in a context on some other class/instance.
list_to_delcould contain dupes or entities loaded from a context and not properly detached.