请查看下面的代码(模型名称已更改以使其更易于阅读)。
模型
// 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'的实体,当使用'Attach'方法或将实体状态设置为'Unchanged'或'Modified'时,如果图中的任何实体具有冲突的键值,则可能会发生这种情况。这可能是因为一些实体是新的,并且尚未收到数据库生成的键值。在这种情况下,请使用“Add”方法或“Added”实体状态来跟踪图形,然后根据需要将非新实体的状态设置为“Unchanged”或“Modified”。
在编辑模型时,是否有人看到我的代码有问题或者了解在什么情况下会引发此类错误?
db
实例是相同的,那么这可能解释了你的问题,因为你的物品是由GET方法加载的(然后被上下文跟踪),而它可能无法将POST方法中获取的实体识别为之前获取的实体。 - Réda MattarcanUserAccessA()
方法是直接加载实体还是作为另一个实体的关系? - CodeCaster