8

Ho un ID con me e ho un nome con me. Quindi, in sostanza, il mio metodo è appena questi parametri:Perché devo cadere in tutti gli ostacoli per un semplice aggiornamento in EF?

public void Foo(int id, string name) 
{ 
} 

e ho questo pezzo di logica metodo all'interno:

User user = new User(){ Id = id, Name = name }; 
Db.Entry(user).State = System.Data.EntityState.Modified; 
Db.SaveChanges(); 

Questo è tutto. Nulla di bello. Ottengo questo errore: "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key"

e questa risposta di Ladislav Mrnka: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key

suggerisce di utilizzare context.Entry(oldEntity).CurrentValues.SetValues(newEntity);, ma io in realtà non hanno oldEntity con me. Qualcuno può dirmi come posso aggiornare solo 1 proprietà dell'utente? Sto diventando matto.

+0

perché non eseguire l'aggiornamento utilizzando la selezione dall'entità anziché eseguire System.Data.EntityState.Modified; –

+2

Non ho esperienza di codice (e quindi non invierò una risposta), ma 'Db' sopra si riferisce a un contesto di database? In tal caso, i contesti nei mondi model-first e database-first sono progettati per essere oggetti di breve durata basati sul modello dell'unità di lavoro. Perché non creare un nuovo contesto per eseguire questa operazione? –

+0

@COLD TOLD: Perché voglio che sia efficiente. Non voglio licenziare 2 richieste solo per aggiornare una singola proprietà di poche decine di proprietà che ho nel mio modello utente. – Jack

risposta

6

I only create once per request, once created I store it inside HttpContext.Items. Hence even though I make multiple request to DB, it uses same DbContext. Does that help?

Se una qualsiasi di queste "richieste multiple al DB" carica l'utente con lo stesso ID otterrete questa eccezione. Provate a usare questo:

public void Foo(int id, string name) { 
    var user = Db.Users.Local.SingleOrDefault(u => u.Id == id); 
    if (user == null) { 
     user = new User { Id = id }; 
     Db.Users.Attach(user); 
    } 

    user.Name = name; 
    Db.SaveChanges(); 
} 

Il codice prima cercare di ottenere un'istanza utente da soggetti già caricati (senza query di database) e crea una nuova istanza solo se l'utente non è stato ancora caricato.

+0

Non aggiorna l'utente solo se si crea e si collega quell'entità stub? Se hai un utente esistente, non lo contrassegni come modificato. –

+1

@JohnH: Apporta modifiche all'utente collegato in modo che non sia necessario modificarne lo stato: EF dovrebbe rilevare la modifica. –

+0

Così fa! Ho sempre dato per scontato che dovessimo farlo per tutto, a meno che non assegnassimo specificamente un'entità. Grazie. –

Problemi correlati