我已经尝试了一段时间来调试这个并以不同的方式表达我想要做的事情,但我没有运气。我不太了解实体框架,我从另一个已经不在的开发人员那里继承了这些代码,所以我不太了解这个模型。也许至少有人能给我指出正确的方向。下面是我的代码:
//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
我有"task",它指向它所属的项目版本。这些项目有很多注释。我想在任务的项目中添加一个新注释。然而,我在最后一行得到了一个异常:
系统。用户代码未处理InvalidOperationException
消息=两个对象之间的关系不能为定义,因为它们附加到不同的ObjectContext对象。
源= System.Data.Entity
这看起来应该是一件非常简单的事情。这样做不对吗?谢谢!
编辑:Ok,我已经从函数中删除了所有其他代码,并创建了一个全新的上下文。下面是从头到尾的整个函数:
//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
我简直不明白怎么会有两个上下文?我在代码的每个地方都使用了"上下文"。实体框架如何使它如此难以简单地添加一行到我的数据库?
问题在
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();
}
尝试设置您的Web。配置连接字符串包括MultipleActiveResultSets=True
好吧,经过近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));
哦,好吧,至少它很快。