实体框架向数据库添加新行时抛出异常

时间:2011-10-06 17:13:07

标签: c# .net asp.net entity-framework

我已经尝试了一段时间来调试这个并用不同的方式表达我想做的事情,但我没有运气。我不太了解实体框架,我从另一个不再有的开发人员那里继承了这个代码,所以我对模型知之甚少。也许有人至少可以让我指出正确的方向。这是我的代码:

//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

我有“任务”,它指向它所属的项目版本。这些项目有很多笔记。我想为任务的项目添加一个新注释。但是,我在最后一行得到了例外:

  

System.InvalidOperationException未被用户代码
处理   Message =两个对象之间的关系不可能   定义因为它们附加到不同的ObjectContext对象   源= System.Data.Entity的

这似乎应该是一件非常简单的事情。这不是正确的方法吗?谢谢!

修改

好的我已从功能中删除了所有其他代码并创建了一个全新的上下文。以下是从头到尾的整个功能:

//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();
}

不过,我得到了同样的例外:

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

我根本无法理解如何有两种情境?我在代码中的每个地方都使用“上下文”。如何简单地将单行添加到我的数据库中,实体框架如何变得如此困难?

3 个答案:

答案 0 :(得分:2)

问题在于

newNote.TPM_USER = SessionHandler.LoginUser;

LoginUser是使用其他上下文创建的。您将其附加到context。有几种方法可以解决这个问题。

从创建的上下文中删除LoginUser

sessionContext.Detach(SessionHandler.LoginUser);

然后在你的方法中

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();
}

或者,如果已映射标量外键属性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();
}

答案 1 :(得分:0)

尝试将Web.Config连接字符串设置为包含MultipleActiveResultSets = True。

答案 2 :(得分:0)

Welp经过将近4个小时的努力才能完成这项工作,唯一可以解决的问题就是这个。显然,将新数据插入数据库是实体框架的一项高级功能,需要深入了解其内部工作原理。

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));

哦,好吧,至少它很快。