Em poucas palavras, a exceção é lançada durante o modelo de wrapper POSTing e alterando o estado de uma entrada para 'Modificado'. Antes de alterar o estado, o estado é definido como 'Desconectado', mas chamar Attach () gera o mesmo erro. Eu estou usando EF6.
Encontre meu código abaixo (os nomes dos modelos foram alterados para facilitar a leitura)
Modelo
// Wrapper classes
public class AViewModel
{
public A a { get; set; }
public List<B> b { get; set; }
public C c { get; set; }
}
Controlador
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);
}
Como mostrado acima da linha
db.Entry(aViewModel.a).State = EntityState.Modified;
lança exceção:
Falha ao anexar uma entidade do tipo 'A' porque outra entidade do mesmo tipo já possui o mesmo valor de chave primária. Isso pode acontecer ao usar o método 'Anexar' ou ao definir o estado de uma entidade como 'Inalterado' ou 'Modificado' se alguma entidade no gráfico tiver valores-chave conflitantes. Isso pode ocorrer porque algumas entidades são novas e ainda não receberam valores-chave gerados pelo banco de dados. Nesse caso, use o método 'Adicionar' ou o estado da entidade 'Adicionado' para rastrear o gráfico e defina o estado de entidades não novas como 'Inalterado' ou 'Modificado', conforme apropriado.
Alguém vê algo errado no meu código ou entende em que circunstâncias isso geraria esse erro durante a edição de um modelo?
db
instância for a mesma entre suas duas ações, ela poderá explicar seu problema, pois o item será carregado pelo método GET (depois rastreado pelo contexto) e poderá não reconhecer o item no método POST como a entidade buscada antes .
canUserAccessA()
carregar a entidade direta ou como uma relação de outra entitiy?
EntityState
? Como sua entidade vem de uma solicitação post, ele não deve ser monitorado pelo contexto atual, eu acho que considera que tentar adicionar um item com um ID existente