Risoluzione di identità, gestione dello stato e rilevamento delle modifiche (Entity Framework)

L'oggetto ObjectContext rappresenta un contenitore per gli oggetti in memoria. Il contesto dell'oggetto, con il supporto di altre classi e interfacce, consente di gestire l'identità e lo stato di un oggetto, nonché i valori originale e corrente delle relative proprietà e di rilevare le modifiche apportate a ogni oggetto nella cache. Per informazioni su come connettere oggetti al contesto dell'oggetto, vedere Connessione e disconnessione di oggetti (Entity Framework). In questo argomento viene descritta la modalità di gestione del rilevamento delle modifiche, della risoluzione delle identità e della gestione dello stato nel contesto dell'oggetto.

Rilevamento delle modifiche

Le informazioni sul rilevamento delle modifiche per l'oggetto grafico vengono archiviate negli oggetti ObjectStateEntry, creati da ObjectContext per ogni oggetto connesso. Gli oggetti ObjectStateEntry archiviano le informazioni seguenti per le entità:

  • EntityKey che determina l'identità di un'entità

  • EntityState dell'oggetto

  • Informazioni sugli oggetti correlati

  • Nome del set di entità

  • CurrentValues e OriginalValues delle proprietà dell'entità (gli oggetti nello stato Added non presentano valori originali)

  • Nomi delle proprietà modificate dell'entità

Per verificare se il valore di una proprietà è stato modificato durante le chiamate a SaveChanges, eseguire una query sulla raccolta di nomi di proprietà modificati restituita dal metodo GetModifiedProperties.

Bb896269.note(it-it,VS.100).gifNota:
Se si utilizzano entità POCO senza proxy di rilevamento delle modifiche, è necessario chiamare DetectChanges prima della chiamata a GetModifiedProperties.

Quando un'entità viene disconnessa, l'oggetto ObjectStateEntry corrispondente viene rimosso dal contesto dell'oggetto.

Gli oggetti ObjectStateEntry vengono gestiti dall'oggetto ObjectStateManager. Per il contesto dell'oggetto esiste un'istanza specifica dell'oggetto ObjectStateManager. Per ottenere l'oggetto ObjectStateEntry per l'entità specificata, utilizzare uno dei metodi seguenti su ObjectStateManager: TryGetObjectStateEntry, GetObjectStateEntry o GetObjectStateEntries.

Il contesto dell'oggetto riceve una notifica sulle modifiche apportate alle proprietà delle entità e degli oggetti proxy di rilevamento delle modifiche POCO generati da Entity Framework quando queste si verificano e aggiorna lo stato degli oggetti e i valori delle proprietà nell'oggetto ObjectStateEntry. Il modello di segnalazione delle modifiche prevede la segnalazione di una modifica in sospeso a una proprietà, l'impostazione della proprietà, quindi la segnalazione del completamento della modifica mediante l'interfaccia IEntityChangeTracker. L'oggetto ObjectStateEntry consente di gestire in modo diverso entità POCO senza oggetti proxy di rilevamento delle modifiche e oggetti di tipo complesso. Per ulteriori informazioni, vedere Rilevamento delle modifiche nelle entità POCO (Entity Framework).

Il contesto dell'oggetto utilizza le informazioni degli oggetti ObjectStateEntry per rendere persistenti i dati nell'origine dati. Per ulteriori informazioni, vedere Salvataggio delle modifiche e gestione della concorrenza (Entity Framework) e Procedura: eseguire la logica di business al momento del salvataggio delle modifiche (Entity Framework).

Risoluzione di identità e opzioni di unione

In Entity Framework viene gestita solo una singola istanza di un oggetto con una chiave di entità specifica nella cache. Gli oggetti EntityKey sono oggetti non modificabili che rappresentano l'identità dell'oggetto. Le chiavi dell'entità sono utilizzate per eseguire la risoluzione di identità nel contesto dell'oggetto. Per ulteriori informazioni, vedere Utilizzo di chiavi di entità (Entity Framework). Se è già stata rilevata un'entità con la stessa identità, i dati dell'origine dati e quelli già presenti nel gestore degli stati vengono uniti in base all'oggetto MergeOption della query.

Nella tabella riportata di seguito sono elencate le possibili opzioni di unione:

Membro Descrizione

AppendOnly

Gli oggetti che non esistono nel contesto dell'oggetto vengono connessi al contesto. Se un oggetto è già presente nel contesto, i valori corrente e originale delle relative proprietà nella voce non vengono sovrascritti con i valori dell'origine dati. Lo stato della voce dell'oggetto e lo stato delle proprietà dell'oggetto nella voce non cambiano. AppendOnly è l'opzione di unione predefinita.

OverwriteChanges

Gli oggetti che non esistono nel contesto dell'oggetto vengono connessi al contesto. Se un oggetto è già presente nel contesto, i valori corrente e originale delle relative proprietà nella voce vengono sovrascritti con i valori dell'origine dati. Lo stato della voce dell'oggetto viene impostato su Unchanged e nessuna proprietà viene contrassegnata come modificata.

PreserveChanges

Gli oggetti che non esistono nel contesto dell'oggetto vengono connessi al contesto.

Se lo stato dell'entità è Unchanged, i valori corrente e originale nella voce vengono sovrascritti con i valori dell'origine dati. Lo stato dell'entità rimane Unchanged e nessuna proprietà viene contrassegnata come modificata.

Se lo stato dell'entità è Modified, i valori correnti delle proprietà modificate non vengono sovrascritti con i valori dell'origine dati. I valori originali delle proprietà non modificate vengono sovrascritti con i valori dell'origine dati.

In .NET Framework versione 4 Entity Framework confronta i valori correnti delle proprietà non modificate con i valori restituiti dall'origine dati. Se i valori non sono gli stessi, la proprietà viene contrassegnata come modificata.

In .NET Framework versione 3.5 SP1 Entity Framework non contrassegna la proprietà come modificata, anche se il valore nell'origine dati è diverso.

Quando si chiama SaveChanges solo le proprietà modificate vengono rese persistenti nell'origine dati.

Per mantenere il comportamento della versione 3.5 SP1, impostare la proprietà UseLegacyPreserveChangesBehavior su true. L'opzione PreserveChanges può essere utilizzata per risolvere eccezioni di concorrenza ottimistica mantenendo le modifiche nel contesto locale. Per ulteriori informazioni, vedere Salvataggio delle modifiche e gestione della concorrenza (Entity Framework).

NoTracking

Gli oggetti vengono mantenuti in uno stato Detached e non vengono rilevati nell'oggetto ObjectStateManager. Tuttavia, le entità generate da Entity Framework e le entità POCO con proxy consentono di gestire un riferimento al contesto dell'oggetto per facilitare il caricamento di oggetti correlati.

Stato dell'entità

Il contesto dell'oggetto deve conoscere lo stato di un oggetto per salvare di nuovo le modifiche nell'origine dati. Negli oggetti ObjectStateEntry sono archiviate le informazioni sull'oggetto EntityState. I metodi SaveChanges di ObjectContext elaborano le entità connesse al contesto e aggiornano l'origine dati in base all'oggetto EntityState di ogni oggetto. Per ulteriori informazioni, vedere Creazione, aggiunta, modifica ed eliminazione di oggetti (Entity Framework). Nella tabella seguente sono indicati gli stati possibili di un oggetto:

Membro Descrizione

Added

L'oggetto è nuovo, è stato aggiunto al contesto dell'oggetto e il metodo SaveChanges non è stato chiamato. Dopo aver salvato le modifiche, lo stato dell'oggetto cambia in Unchanged. Gli oggetti nello stato Added non presentano valori originali in ObjectStateEntry.

Deleted

L'oggetto è stato eliminato dal contesto dell'oggetto. Dopo aver salvato le modifiche, lo stato dell'oggetto cambia in Detached.

Detached

L'oggetto esiste ma non ne viene eseguito il rilevamento. Un'entità si trova in questo stato subito dopo la creazione e prima dell'aggiunta al contesto dell'oggetto. Un'entità si trova in questo stato anche dopo essere stata rimossa chiamando il metodo Detach o nel caso in cui sia stata caricata mediante un oggetto MergeOption NoTracking. Nessuna istanza ObjectStateEntry è associata a oggetti nello stato Detached.

Modified

Una delle proprietà scalari dell'oggetto è stata modificata e il metodo SaveChanges non è stato chiamato. Nelle entità POCO senza proxy di rilevamento delle modifiche lo stato delle proprietà modificate cambia in Modified quando viene chiamato il metodo DetectChanges. Dopo aver salvato le modifiche, lo stato dell'oggetto cambia in Unchanged.

Unchanged

L'oggetto non è stato modificato dopo la connessione al contesto o dopo l'ultima chiamata al metodo SaveChanges.

Lo stato degli oggetti in un contesto dell'oggetto viene gestito da ObjectStateManager. Per conoscere lo stato di un oggetto, chiamare uno dei seguenti metodi di ObjectStateManager: TryGetObjectStateEntry, GetObjectStateEntry o GetObjectStateEntries. La proprietà State dell'oggetto ObjectStateEntry consente di definire lo stato dell'oggetto.

Vedere anche

Concetti

Utilizzo di chiavi di entità (Entity Framework)