简而言之,在POSTing包装器模型并将一个条目的状态更改为“已修改”期间会引发异常。在更改状态之前,将状态设置为“已分离”,但是调用Attach()确实会引发相同的错误。我正在使用EF6。
请在下面找到我的代码(型号名称已更改,以便于阅读)
模型
// Wrapper classes
public class AViewModel
{
public A a { get; set; }
public List<B> b { get; set; }
public C c { get; set; }
}
控制者
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (!canUserAccessA(id.Value))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
var aViewModel = new AViewModel();
aViewModel.A = db.As.Find(id);
if (aViewModel.Receipt == null)
{
return HttpNotFound();
}
aViewModel.b = db.Bs.Where(x => x.aID == id.Value).ToList();
aViewModel.Vendor = db.Cs.Where(x => x.cID == aViewModel.a.cID).FirstOrDefault();
return View(aViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(AViewModel aViewModel)
{
if (!canUserAccessA(aViewModel.a.aID) || aViewModel.a.UserID != WebSecurity.GetUserId(User.Identity.Name))
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
if (ModelState.IsValid)
{
db.Entry(aViewModel.a).State = EntityState.Modified; //THIS IS WHERE THE ERROR IS BEING THROWN
db.SaveChanges();
return RedirectToAction("Index");
}
return View(aViewModel);
}
如上线所示
db.Entry(aViewModel.a).State = EntityState.Modified;
引发异常:
附加类型“ A”的实体失败,因为相同类型的另一个实体已经具有相同的主键值。如果图形中的任何实体具有冲突的键值,则使用“附加”方法或将实体的状态设置为“不变”或“修改”时,可能会发生这种情况。这可能是因为某些实体是新实体,尚未收到数据库生成的键值。在这种情况下,请使用“添加”方法或“已添加”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
是否有人在我的代码中看到任何错误或了解在什么情况下在编辑模型时会引发此类错误?
db
您的两个操作之间的实例相同,则可以解释您的问题,因为您的商品是通过GET方法加载的(然后由上下文跟踪),并且可能无法将POST方法中的实例识别为之前获取的实体。
canUserAccessA()
直接或作为另一entitiy的关系加载实体?
EntityState
?当你的实体来自POST请求,它不应该由当前上下文跟踪,我猜测它认为你试图与现有的ID添加一个项目