实体框架错误:ObjectStateManager中已存在具有相同密钥的对象

时间:2013-10-17 21:21:29

标签: asp.net asp.net-mvc entity-framework asp.net-mvc-4 entity-framework-5

我得到了这个错误

  

ObjectStateManager中已存在具有相同键的对象。   ObjectStateManager无法跟踪具有相同对象的多个对象   键。

仅因为这一行

oldProject = db.Projectes.Find(project.ID);

我需要它才能在编辑之前获取对象,然后比较编辑之前和之后的值变化,我在第三个if语句中进行比较(比较一个值) ,以及“SFSiteEmailSend.ProjectEdited”功能,仅检查更改并发送有关它的电子邮件。

顺便说一句,我从不更改“oldproject”,即使删除了所有的电子邮件功能和第三个(最后一个)if语句,错误仍然存​​在。

        // POST: /Project/Edit/5

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(Project project)
    {
        if (ModelState.IsValid)
        {  

            // For Email Send - start
            string UrlProject = Request.Url.GetLeftPart(UriPartial.Authority) + Url.Action("Detail", "Project", new { id = project.ID });
            Project oldProject = new Project();
            Project newProject = new Project();
            newProject = project;
            oldProject = db.Projectes.Find(project.ID);
            SFSiteEmailSend.ProjectEdited(oldProject, newProject, UrlProject);
            // For Email Send - end

            if (oldProject.Finished == false && newProject.Finished == true)
            {
                project.DateFinished = DateTime.Now;
            }
            db.Entry(project).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(project);
    }

3 个答案:

答案 0 :(得分:1)

您的代码充满了冗余。剥去一部分它应该更容易发现错误:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Project newProject)
{
   if (ModelState.IsValid)
   {
       string UrlProject = Request.Url.GetLeftPart(UriPartial.Authority) 
                         + Url.Action("Detail", "Project", new { id = newProject.ID });

       //both oldProject and newProject have the same Key but only oldProject 
       //is attached
       Project oldProject = db.Projectes.Find(newProject.ID);

       SFSiteEmailSend.ProjectEdited(oldProject, newProject, UrlProject);

       if (!oldProject.IsFinished && newProject.IsFinished )
          newProject.DateFinished = DateTime.Now;

       //now you try to attach another project with the same Key. 
       //It will fail when you call SaveChanges         
       db.Entry(newProject).State = EntityState.Modified;

      //This is an option:
      d.Entry(oldProject).State = EntityState.Detached;

      db.SaveChanges();
      return RedirectToAction("Index");
   }
   return View(newProject);
}

或者您可以首先加载oldProject AsNoTracking - 正如您已经发现的那样

答案 1 :(得分:1)

试试 project.entitykey = oldproject.entitykey
在savechanges之前

答案 2 :(得分:0)

我找到了解决方案

相反

public ActionResult Edit(Project project)
    {
     Project beforeEditProject = db.Projectes.Find(project.ID);
     .... 
    }

}

使用

public ActionResult Edit(Project project)
        {
          Project beforeEditProject = db.Projectes.AsNoTracking().First(p => p.ID == project.ID);
          .....
        }