Comment puis-je modifier une entité utilisant le code Entity Framework Première approche?

StackOverflow https://stackoverflow.com/questions/4650077

  •  09-10-2019
  •  | 
  •  

Question

J'ai été déchirer mes cheveux sur ce pendant des jours et avant que je parte complètement chauve, il est temps de demander à tous les gens plus intelligents que moi comment faire.

J'utilise Entity Framework 4 avec le premier code CTP 5 et MVC 3.

Le message d'exception est en ce moment « Un objet avec la même clé existe déjà dans le ObjectStateManager. Le ObjectStateManager ne peut pas suivre plusieurs objets avec la même clé. »

Le premier est le contrôleur ici le formulaire de modification est affiché à:

public ActionResult Save(ClientEntity postedClient)
    {
        try
        {
            if (ModelState.IsValid)
            {
                Base.clientInterface.Save(postedClient);
                return RedirectToAction("Index");
            }
        }
        catch (Exception)
        {

            throw;
        }

        SetupManageData(null, postedClient);
        return View("Manage");

    }

La méthode Save sur l'interface client est la suivante:

public void Save(ClientEntity theClient)
    {
        SetContext();


        if (theClient.clientId == 0)
            this.pContext.Clients.Add(theClient);
        else
        {
            ClientEntity existingClient = GetSingle(theClient.clientId); // Get the existing entity from the data store.

            // PseudoCode: Merge existingClient and theClient - Can this be done without using ObjectStateManager?               
            // PseudoCode: Attach merged entity to context so that SaveChanges will update it in the database - is this correct?
        }

        this.pContext.SaveChanges();

    }

    private void SetContext()
    {
        if (this.pContext == null)
            this.pContext = new PersistanceContext();           
    }

est le contexte Persistance DBContext et ressemble à ceci:

public class PersistanceContext : DbContext
{
    public DbSet<ClientEntity> Clients { get; set; }
}
Était-ce utile?

La solution

Quel est le mode de vie de clientInterface? est-il un singleton ou quelque chose qui le maintient en vie à travers de multiples demandes?

Je suppose qu'il détient une instance en direct d'un contexte de base de données qui a été utilisé pour récupérer l'entité dans la requête GET et lorsque le POST essaie de (re) ajouter une entité cliente au contexte de l'ancien est toujours là et ils entrent en conflit.

Essayez de détruire l'objet qui se trouve derrière le clientInterface à chaque demande. Peut-être utiliser un conteneur DI que le soutien par-WebRequest modes de vie de sorte que vous n'avez pas à vous parler.

J'espère que je pense était juste et c'est de l'aide.

Autres conseils

Cela devrait fonctionner.

    if (theClient.clientId == 0)
    {
        this.pContext.Clients.Add(theClient);
    }
    else
    {
        ClientEntity existingClient = this.pContext.Clients.Single(o => o.ClientId == theClient.ClientId);

        // map properties
        existingClient.Name = theClient.name;
        // ....

    }

    this.pContext.SaveChanges();

[Modifier]

Il est plus facile (à mon humble avis) pour diviser la création et l'édition d'objets en 2 vues séparées et d'éviter la mise en correspondance des propriétés que j'utilise TryUpdateModel.

[HttpPost]
public ViewResult Edit(int clientID, FormCollection collection) 
{
    var client = pContext.Clients.SingleOrDefault(o => o.ID == clientID);

    if(!TryUpdateModel(client, collection)) 
    {
        ViewBag.UpdateError = "Update Failure";
    }
    else
    {
        db.SubmitChanges();
    }

    return View("Details", client); 
}

[HttpPost]
public ViewResult Create(FormCollection collection) 
{
    var client = new Client();

    if(!TryUpdateModel(client, collection)) 
    {
        ViewBag.UpdateError = "Create Failure";
    }
    else
    {
        db.Clients.Add(client);
        db.SubmitChanges();
    }

    return View("Details", client); 
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top