1

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?

3 Answers 3

2

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();
}
Sign up to request clarification or add additional context in comments.

Comments

0

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

8 Comments

So what's your reasoning? Is this because I'm doing a bunch of editing with the "task" and I can't add new relations to it at the same time?
Ah...not using MS SQL. I had a similar problem and making the change fixed it. Not sure exactly how EF handles DB transactions, but I do know that it has to do handle multiple result sets to maintain it's OO approach. I usually load the DB context as a module level variable and use it throughout the class so I don't get issues with multiple context objects. (Note: sometimes you need multiple contexts).
Yea this code is happening within a using() block which creates the context. There /should/ only be one context..
Is 'task' defined inside, outside or as a parameter of the using() block?
Not really. Task is declared within the using block, but we load it with a function: task = TaskManager.GetTaskIfExists(context, this.TaskId); -- However, that function uses the same context and dose a LINQ query to load the TPM_TASK object from the database. Since the context was passed in, that should be fine right?
|
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.