Come faccio a modificare un'entità utilizzando l'Entity Framework Codice Primo approccio?

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

  •  09-10-2019
  •  | 
  •  

Domanda

Sono stato strappando i capelli fuori sopra questo per giorni e prima di andare completamente calvo è il momento di chiedere a tutte le persone più intelligenti di me come fare questo.

Sto utilizzando Entity Framework 4 del Codice primo CTP 5 e MVC 3.

Il messaggio di eccezione in questo momento è "Un oggetto con la stessa chiave esiste già nella ObjectStateManager. L'ObjectStateManager non può monitorare più oggetti con la stessa chiave."

In primo luogo qui è il controller del modulo di modifica viene inviato a:

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");

    }

Il metodo Save sull'interfaccia del client è questa:

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();           
    }

contesto Persistenza è il DbContext e si presenta così:

public class PersistanceContext : DbContext
{
    public DbSet<ClientEntity> Clients { get; set; }
}
È stato utile?

Soluzione

Qual è lo stile di vita di clientInterface? si tratta di un singolo o di qualcosa che tiene in vita attraverso più richieste?

La mia ipotesi è che abbia un esempio vivo di un contesto di database che è stato utilizzato per andare a prendere l'entità della richiesta GET e quando il POST cerca di (ri) aggiungere un'entità client al contesto, il vecchio è ancora lì e sono in conflitto.

Prova distruggere l'oggetto che si trova dietro il clientInterface con ogni richiesta. Forse utilizzare un contenitore DI supportati per-WebRequest stili di vita in modo da non devono preoccuparsi.

Spero che la mia ipotesi era giusta e questo è di aiuto.

Altri suggerimenti

Questo dovrebbe funzionare.

    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();

[Modifica]

E 'più facile (IMHO) per dividere la creazione e la modifica di oggetti in 2 viste separate e per evitare la mappatura delle proprietà che uso 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); 
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top