2011-08-18 9 views
36

La documentazione ufficiale dice di modificare un'entità. Richiamo un oggetto DbEntityEntry e lavoro con le funzioni di proprietà o imposto il suo stato su modificato. Esso utilizza il seguente esempioEntity Framework: perché impostare in modo esplicito lo stato dell'entità su modificato?

Department dpt = context.Departments.FirstOrDefault(); 
DbEntityEntry entry = context.Entry(dpt); 
entry.State = EntityState.Modified; 

non capisco lo scopo della dichiarazione di 2 ° e 3 °. Se chiedo il quadro per un soggetto come la prima dichiarazione non e quindi modificare il POCO come in

dpt.Name = "Blah" 

Se dunque io chiedo EF per SaveChanges(), l'entità ha uno stato di MODIFICATO (io sono indovinando tramite il tracciamento di istantanee, questo non è un proxy) e le modifiche vengono mantenute senza la necessità di impostare manualmente lo stato. Mi sto perdendo qualcosa qui?

risposta

38

Nel tuo scenario, in effetti, non è necessario impostare lo stato. È lo scopo del rilevamento delle modifiche per scoprire che hai modificato un valore sull'entità associata e lo hai messo in stato modificato. Lo stato di impostazione manuale è importante in caso di entità distaccate (entità caricate senza tracciamento delle modifiche o create al di fuori del contesto corrente).

+4

Grazie per la conferma. Molti tutorial che ho letto sembrano utilizzare questo approccio che è fonte di confusione. – SeeNoWeevil

16

Come detto, in uno scenario con entità disconnesse può essere utile impostare lo stato di un'entità su Modified. Salva un roundtrip sul database se si collega l'entità disconnessa, anziché prelevare l'entità dal database e modificarla e salvarla.

Ma ci possono essere ottimi motivi per non impostare lo stato su Modified (e sono sicuro che Ladislav era a conoscenza di questo, ma comunque vorrei indicarlo qui).

  1. Tutti i campi nel record verranno aggiornati, non solo le modifiche. Esistono molti sistemi in cui vengono controllati gli aggiornamenti. L'aggiornamento di tutti i campi causerà grandi quantità di ingombro o richiederà il meccanismo di controllo per filtrare le false modifiche.

  2. Concorrenza ottimistica. Poiché tutti i campi sono aggiornati, ciò potrebbe causare più conflitti del necessario. Se due utenti aggiornano gli stessi record contemporaneamente ma non gli stessi campi, non è necessario che ci sia un conflitto. Ma se aggiornano sempre tutti i campi, l'ultimo utente cercherà sempre di scrivere dati obsoleti. Ciò nel migliore dei casi causerà un'eccezionale eccezione di concorrenza o nel caso peggiore la perdita di dati.

  3. Aggiornamenti inutili. L'entità è contrassegnata come modificata, indipendentemente da cosa. Le entità invariate genereranno anche un aggiornamento. Ciò può facilmente verificarsi se è possibile aprire le finestre di modifica per visualizzare i dettagli e chiudere con OK.

Quindi è un buon equilibrio. Riduci i roundtrip o riduci la ridondanza.

Comunque, l'alternativa di impostare lo stato di Modified è (utilizzando DbContext API):

void UpdateDepartment(Department department) 
{ 
    var dpt = context.Departments.Find(department.Id); 
    context.Entry(dpt).CurrentValues.SetValues(department); 
    context.SaveChanges(); 
} 

CurrentValues.SetValues segna singole proprietà come Modified.

+0

@GertAmold, potresti specificare lo spazio dei nomi in cui si trova 'CurrentValues.SetValues'. Posso raggiungerlo in ** ASP.NET Core 1.0 ** –

Problemi correlati