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

sfg*_*ups 52 entity-framework asp.net-mvc-3

我有以下代码来添加或更新Entity对象.根据我添加或更新对象的响应,通过主键查找对象.

添加记录工作,但在更新期间它给出此错误消息" ObjectStateManager中已存在具有相同键的对象.ObjectStateManager无法跟踪具有相同键的多个对象"

在我的MSSQL数据库中,我只有一条记录.

var v = db.Envelopes.Find(model.ReportDate, model.Service);
if (v == null)
{
    db.Envelopes.Add(model);
    db.SaveChanges();
    ViewBag.status = "Record Add successfully";
    ModelState.Clear();
}
else
{
    db.Entry(model).State = EntityState.Modified;
    db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

我该如何修复此错误消息?

Lad*_*nka 88

正如@anon所提到的,一旦您使用相同的密钥加载实体,就无法附加模型.必须将更改应用于附加实体.而不是这个:

db.Entry(model).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)

用这个:

db.Entry(v).CurrentValues.SetValues(model);
Run Code Online (Sandbox Code Playgroud)

  • @Sanghoon如果`model`的ID与`v`的ID不同,你可能会得到那个错误.所以你可能想在调用`SetValues`之前添加类似`model.SetId(v.GetId());`的东西. (3认同)
  • 它看起来很有希望,但它导致"属性'ID'是对象的关键信息的一部分,无法修改." 那么,有没有办法从模型中删除主键? (2认同)

tdy*_*tra 9

如果先前的查询读取要更新的实体并且这就是您收到错误的原因,则可以将该查询更改为AsNoTracking.请参阅AsNoTracking示例:http: //www.asp.net/entity-framework/tutorials/advanced-entity-framework-scenarios-for-an-mvc-web-application

  • 是的 - EF中的任何东西似乎都没有像你期望的那样工作.我用过的最烦人的ORM. (34认同)
  • 我使用AsNoTracking,它仍然给我这个错误 (2认同)

ano*_*non 7

我假设你说你的错误发生在这里:

db.Entry(model).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)

执行Find()后,您的Envelope已被您的上下文跟踪.这意味着如果您需要更改属性,只需在v上更改它,然后调用SaveChanges().不要担心将状态设置为Modified.

  • 正确.我尝试使用新的Context来绕过这个,但它也没有用.ObjectTracker仍然有一个对它的引用. (3认同)

Dav*_*lls 5

如果将上下文设置为AsNoTracking(),则会停止aspmvc跟踪内存中实体的更改(这是您在网络上无论如何).不要忘记使用声明.

using System.Data.Entity;

db.Envelopes.AsNoTracking().Find(model.ReportDate, model.Service);
Run Code Online (Sandbox Code Playgroud)

我从这个论坛帖子中得到了这个 - > http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for-an-mvc-web -应用