Utilizzo di chiavi di entità (Entity Framework)

Ciascun tipo di entità dispone di una chiave basata su una o più proprietà scalari dell'entità. Le chiavi vengono definite dall'elemento Key nel modello concettuale. Analogamente ai database relazionali, questi valori di chiave vengono utilizzati per verificare l'univocità dell'entità specificata e migliorare le prestazioni delle query. Le proprietà della chiave sono in genere mappate a una colonna di chiave, ovvero una colonna di identità o un'altra colonna vincolata per garantire un valore univoco, della tabella sottostante. Per ulteriori informazioni sulla definizione delle chiavi nel modello concettuale, vedere Elemento Key (CSDL).

Quando una query di oggetto restituisce un oggetto, Entity Framework consente di materializzare l'oggetto entità e la chiave di entità in un'istanza della classe EntityKey. È possibile accedere alla classe EntityKey dalla proprietà EntityKey di un oggetto che implementa IEntityWithKey. IEntityWithKey viene inoltre implementato dalla classe base per tutte le classi di dati generati dagli strumenti di Entity Data Model , EntityObject.

Dd283139.note(it-it,VS.100).gifNota:
Con Entity Framework non è necessario implementare IEntityWithKey in una classe di dati personalizzata.

Costruzione e utilizzo di un oggetto EntityKey

Un oggetto EntityKey è costituito dalle proprietà EntitySetName e EntityContainerName, nonché da una matrice di una o più coppie chiave/valore. Una coppia chiave/valore è costituita da un nome e un valore di proprietà. Le coppie chiave/valore vengono fornite come uno o più oggetti EntityKeyMember nella proprietà EntityKeyValues.

Dd283139.note(it-it,VS.100).gifNota:
Quando si utilizza uno dei costruttori EntityKey, al parametro qualifiedEntitySetName viene fornito il valore stringa EntitySetName preceduto da EntityContainerName, come in "NomeContenitoreEntità.NomeSetEntità".

Per ottenere EntityKey per un oggetto disconnesso, è anche possibile utilizzare il metodo CreateEntityKey su ObjectContext. Se l'oggetto non dispone di una chiave valida, nel contesto dell'oggetto viene costruita una nuova istanza di EntityKey per l'oggetto specificato. Per ulteriori informazioni, vedere Procedura: creare istanze di EntityKey (Entity Framework).

Una chiave di entità identifica in modo univoco un'entità, è pertanto possibile creare un'entità solo con la chiave e collegare l'oggetto a un contesto dell'oggetto anche se i valori restanti dell'oggetto non vengono recuperati dall'origine dati. Per ulteriori informazioni, vedere Procedura: connettere oggetti correlati (Entity Framework). È inoltre possibile utilizzare una chiave di entità per recuperare un oggetto dal contesto dell'oggetto o dall'origine dati. Per ulteriori informazioni, vedere Procedura: restituire un oggetto specifico utilizzando la relativa chiave (Entity Framework).

Chiavi di entità a lunghezza fissa

Entity Framework esegue una risoluzione di identità in base al valore di EntityKey, che corrisponde a una chiave primaria nel database. Se una query restituisce un oggetto con un valore di EntityKey già esistente in ObjectContext, non viene creato un nuovo oggetto. Se si utilizzano colonne con dimensione fissa nel database e si salvano in modo permanente valori di dimensioni più ridotte rispetto a quelle specificate nel database, in alcuni database i tipi a dimensione fissa verranno completati con spazi o zeri. In SQL Server i tipi di stringa a dimensione fissa vengono riempiti con spazi finali. Se i tipi a dimensione fissa (ad esempio binario o char) vengono utilizzati come chiavi primarie, potrebbero verificarsi problemi di risoluzione di identità.

Si osservi l'esempio riportato di seguito. Nella tabella Product è presente una colonna a lunghezza fissa di dimensione 10 per la chiave primaria. Un oggetto Product con EntityKey AB100 viene creato e aggiunto a ObjectContext. Quando l'oggetto viene salvato nel database, la chiave viene completata con spazi finali, in quanto la colonna è a dimensione fissa e le dimensioni del valore salvato sono più ridotte di quelle specificate nel database. Una successiva query per un oggetto con valore EntityKey pari a AB100 restituirà un oggetto con un valore EntityKey diverso (AB100 seguito da spazi finali) in quanto in SQL Server AB100 corrisponde alla stringa riempita. In Entity Framework i valori di proprietà non vengono né completati né tagliati. Di conseguenza, a ObjectContext viene aggiunto un nuovo oggetto con EntityKey AB100 seguito da spazi finali.

Product p1= new Product 
{ 
    ProductID = "AB100", 
    Description = "New product" 
}; 
// An object with EntityKey "AB100" is added to ObjectContext.  ctx.Products.AddObject(p1); 
// The object is saved in the database with a primary key of 
// "AB100     " because the column is of a fixed size.  ctx.SaveChanges();
// When a query is executed for an object with key "AB100", SQL Server // matches the key to "AB100     ".  The result is that a new object 
// with EntityKey "AB100     " is added to ObjectContext.  Product p2 = ctx.Products.First(p => p.ProductCode == "AB100");  

Per ovviare a questo comportamento indesiderato, è possibile effettuare una delle operazioni riportate di seguito.

  • Utilizzare un tipo di lunghezza variabile anziché fissa nel database.

  • Completare il valore di EntityKey con spazi finali o zeri nel client. È possibile utilizzare metodo PadRight per inserire spazi in una stringa.

Chiavi di entità e oggetti aggiunti

Quando viene creata una nuova entità, Entity Framework definisce una chiave temporanea e imposta la proprietà IsTemporary su true. Quando si chiama il metodo SaveChanges, Entity Framework assegna una chiave permanente e imposta la proprietà IsTemporary su false.

Se il valore della colonna corrispondente è un'identità generata nel database, impostare l'attributo StoreGeneratedPattern dell'elemento Property di un'entità nel modello di archiviazione su Identity. Quando gli strumenti di Entity Data Model generano un modello di dati da un'origine dati esistente, l'attributo StoreGeneratedPattern viene aggiunto a ogni elemento Elemento Property (CSDL) che rappresenta un'identità o una colonna calcolata nell'origine dati. Dopo la chiamata a SaveChanges, Entity Framework sostituisce il valore della proprietà di una chiave temporanea con il valore di identità generato dall'origine dati.

Di seguito viene illustrato il processo interno che sostituisce la chiave temporanea con una chiave permanente contenente i valori generati dal server.

  1. Viene costruito l'oggetto entità.

    In questa fase tutte le proprietà della chiave dispongono di valori predefiniti, null o 0.

  2. Il nuovo oggetto viene aggiunto a ObjectContext mediante chiamata al metodo AddObject su ObjectContext o ObjectSet oppure aggiungendo un oggetto alla raccolta di oggetti sul lato "molti" della relazione.

    A questo punto Entity Framework genera una chiave temporanea utilizzata per archiviare gli oggetti in ObjectStateManager.

  3. Viene chiamato SaveChanges su ObjectContext.

    Un'istruzione INSERT viene generata in Entity Framework ed eseguita sull'origine dati.

  4. Se l'operazione INSERT ha esito positivo, i valori generati dal server vengono scritti in ObjectStateEntry.

  5. ObjectStateEntry aggiorna l'oggetto con il valore generato dal server.

  6. Quando il metodo AcceptChanges viene chiamato su ObjectStateEntry, viene calcolata una chiave permanente EntityKey tramite i nuovi valori generati dal server.

    Dd283139.note(it-it,VS.100).gifNota:
    AcceptChanges viene chiamato in modo automatico al termine dell'esecuzione di SaveChanges o quando il metodo SaveChanges viene chiamato con il flag AcceptAllChangesAfterSave.

  7. ObjectStateManager sostituisce tutte le istanze della chiave temporanea con la nuova chiave permanente.

Valori di proprietà GUID

In Entity Framework sono supportate le proprietà dell'entità che restituiscono un tipo Guid per assicurarne l'univocità.

In Entity Framework sono supportati i valori di identità del tipo GUID generati dal server, ma il provider deve essere in grado di restituire il valore di identità generato dal server dopo l'inserimento di una riga. In SQL Server è possibile restituire il tipo GUID generato dal server tramite la clausola OUTPUT a partire da SQL Server 2005. Se un provider non supporta l'equivalente della clausola OUTPUT, è necessario generare i valori GUID per i nuovi oggetti nel client. A questo scopo, si consiglia di gestire l'evento SavingChanges per generare un nuovo valore GUID per qualsiasi oggetto entità in stato Added. Per ulteriori informazioni, vedere Procedura: eseguire la logica di business al momento del salvataggio delle modifiche (Entity Framework).

Quando si genera o si aggiorna un modello di dati con la Entity Data Model Wizard o la Update Model Wizard, le proprietà GUID dei tipi di entità vengono generate automaticamente per le colonne tipizzate uniqueidentifier nell'origine dati. Un'origine dati può anche utilizzare colonne binarie a 16 byte per archiviare valori GUID. Poiché gli strumenti generano una proprietà binaria per ogni colonna binaria nell'origine dati, è necessario aggiornare manualmente il mapping di tali colonne alle proprietà GUID modificando il file con estensione edmx. Per ulteriori informazioni, vedere How to: Map a GUID Property to a Binary Column.

Contenuto della sezione

Procedura: creare istanze di EntityKey (Entity Framework)

Vedere anche

Attività

Procedura: creare istanze di EntityKey (Entity Framework)

Altre risorse

Entity Data Model Tools