Mike Christensen
Mike Christensen

Reputation: 91580

Exception thrown with Entity Framework adding new row to the DB

I've been trying for a while to debug this and express what I want to do in different ways, but am having no luck. I don't know a whole lot about the entity framework, and I inherited this code from another developer who's no longer around so I don't know a whole lot about the model. Perhaps someone can at least get me pointed in the right direction. Here's my code:

//Append note to project notes too
task.TPM_PROJECTVERSIONReference.Load();
TPM_PROJECTVERSIONNOTES newNote = new TPM_PROJECTVERSIONNOTES();
newNote.TS = System.DateTime.Now;
newNote.TPM_USER = SessionHandler.LoginUser;
newNote.NOTES = task.NOTES;
newNote.PROJECTID = this.ProjectId;
newNote.VERSIONID = this.VersionId;
task.TPM_PROJECTVERSION.TPM_PROJECTVERSIONNOTES.Add(newNote); //<-- Exception

I have "task", which points to a project version it belongs to. These projects have a bunch of notes. I want to add a new note to the task's project. However, I get an exception on the last line:

System.InvalidOperationException was unhandled by user code
Message=The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
Source=System.Data.Entity

This seems like it should be a pretty simple thing. Is this not the right way to do this? Thanks!

Edit:

Ok I've removed ALL other code from the function and created a brand new context. Here's the entire function now from start to finish:

//Append note to project notes too
using (TPMEntities context = new TPMEntities(General.EntityName()))
{
   TPM_PROJECTVERSIONNOTES newNote = context.TPM_PROJECTVERSIONNOTES.CreateObject();
   newNote.TS = System.DateTime.Now;
   newNote.TPM_USER = SessionHandler.LoginUser;
   newNote.NOTES = this.txtTaskNotes.Text;
   TPM_PROJECTVERSION version = (from pv in context.TPM_PROJECTVERSION
                                 where pv.PROJECTID == this.ProjectId && pv.VERSIONID == this.VersionId
                                 select pv).First();

   version.TPM_PROJECTVERSIONNOTES.Add(newNote);
   context.SaveChanges();
}

Still, I get the same exception:

System.InvalidOperationException was unhandled by user code
  Message=The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
  Source=System.Data.Entity

I simply can't understand how there can be two contexts? I'm using "context" every single place in the code. How can the Entity Framework make it so difficult to simply add a single row into my database?

Upvotes: 1

Views: 1237

Answers (3)

Eranga
Eranga

Reputation: 32437

The problem is in

newNote.TPM_USER = SessionHandler.LoginUser;

LoginUser is created using another context. You are attaching that to context. There are couple of ways to solve this.

Detach the LoginUser from the context it was created.

sessionContext.Detach(SessionHandler.LoginUser);

Then inside your method

using (TPMEntities context = new TPMEntities(General.EntityName()))
{
   context.Attach(SessionHandler.LoginUser);

   TPM_PROJECTVERSIONNOTES newNote = context.TPM_PROJECTVERSIONNOTES.CreateObject();
   newNote.TS = System.DateTime.Now;
   newNote.TPM_USER = SessionHandler.LoginUser;
   newNote.NOTES = this.txtTaskNotes.Text;
   TPM_PROJECTVERSION version = (from pv in context.TPM_PROJECTVERSION
                                 where pv.PROJECTID == this.ProjectId && pv.VERSIONID == this.VersionId
                                 select pv).First();

   version.TPM_PROJECTVERSIONNOTES.Add(newNote);
   context.SaveChanges();
}

Or if you have mapped the scalar foreign key property newNote.TPM_USER_ID

using (TPMEntities context = new TPMEntities(General.EntityName()))
{
   TPM_PROJECTVERSIONNOTES newNote = context.TPM_PROJECTVERSIONNOTES.CreateObject();
   newNote.TS = System.DateTime.Now;
   newNote.TPM_USER_ID = SessionHandler.LoginUser.ID;
   newNote.NOTES = this.txtTaskNotes.Text;
   TPM_PROJECTVERSION version = (from pv in context.TPM_PROJECTVERSION
                                 where pv.PROJECTID == this.ProjectId && pv.VERSIONID == this.VersionId
                                 select pv).First();

   version.TPM_PROJECTVERSIONNOTES.Add(newNote);
   context.SaveChanges();
}

Upvotes: 2

Mike Christensen
Mike Christensen

Reputation: 91580

Welp after nearly 4 hours of trying to make this work, the only solution I could actually get working is this one. Apparently inserting new data into the database is an advanced feature of the Entity Framework that require in-depth knowledge of its inner workings.

context.ExecuteStoreQuery<object>("INSERT INTO TPM_PROJECTVERSIONNOTES (NOTES, PROJECTID, VERSIONID, USERID, TS) VALUES (:notes, :projId, :versionId, :userId, :timestamp)",
   new OracleParameter("notes", this.txtTaskNotes.Text),
   new OracleParameter("projId", this.ProjectId),
   new OracleParameter("versionId", this.VersionId),
   new OracleParameter("userId", SessionHandler.LoginUser.USERID),
   new OracleParameter("timestamp", DateTime.Now));

Oh well, at least it's fast.

Upvotes: 0

Watermark Studios
Watermark Studios

Reputation: 1183

Try setting your Web.Config Connection String to include MultipleActiveResultSets=True.

Upvotes: 0

Related Questions