Utilisation des clés d'entité (Entity Framework)

Chaque type d'entité possède une clé basée sur une ou plusieurs propriétés scalaires de l'entité. Les clés sont définies par l'élément Key dans le modèle conceptuel. Comme dans les bases de données relationnelles, ces valeurs de clé sont utilisées pour vérifier l'unicité d'une entité donnée et améliorer la performance des requêtes. Habituellement, les propriétés de clé sont mappées à une colonne de clé dans la table sous-jacente, ou bien à une colonne d'identité ou à une autre colonne qui est contrainte de garantir une valeur unique. Pour plus d'informations sur la façon dont les clés sont définies dans le modèle conceptuel, consultez Élément Key (CSDL).

Lorsqu'un objet est retourné par une requête d'objet, Entity Framework matérialise l'objet entité. Il matérialise également la clé d'entité dans une instance de la classe EntityKey. Vous pouvez accéder à EntityKey depuis la propriété EntityKey d'un objet qui implémente IEntityWithKey. EntityObject est la classe de base de toutes les classes de données générées par les outils Entity Data Model et implémente également IEntityWithKey.

Dd283139.note(fr-fr,VS.100).gifRemarque :
Entity Framework ne requiert pas que vous implémentiez IEntityWithKey dans une classe de données personnalisée.

Construction et utilisation d'un objet EntityKey

Un objet EntityKey est composé des propriétés EntitySetName et EntityContainerName et d'un tableau d'une ou plusieurs paires clé/valeur. Une paire clé/valeur consiste en un nom de propriété et en une valeur de propriété. Vous fournissez des paires clé/valeur sous la forme d'un ou plusieurs objets EntityKeyMember dans la propriété EntityKeyValues.

Dd283139.note(fr-fr,VS.100).gifRemarque :
Lorsque vous utilisez l'un des constructeurs EntityKey, la valeur de chaîne fournie au paramètre qualifiedEntitySetName est le EntitySetName ajouté par EntityContainerName, comme dans « EntityContainerName.EntitySetName ».

Vous pouvez également utiliser la méthode CreateEntityKey sur ObjectContext pour recevoir le EntityKey pour un objet détaché. Si l'objet n'a pas de clé valide, le contexte de l'objet construit une nouvelle instance EntityKey pour l'objet spécifié. Pour plus d'informations, consultez Procédure : créer un EntityKey (Entity Framework).

Étant donné qu'une clé d'entité identifie de façon unique une entité, vous pouvez créer une entité avec une simple clé et joindre l'objet à un contexte d'objet, même si les valeurs d'objet restantes n'ont pas été récupérées depuis la source de données. Pour plus d'informations, consultez Procédure : attacher des objets connexes (Entity Framework). Une clé d'entité peut également être utilisée pour récupérer un objet à partir du contexte de l'objet ou de la source de données. Pour plus d'informations, consultez Procédure : retourner un objet spécifique à l'aide de sa clé (Entity Framework).

Clés d'entité de longueur fixe

Entity Framework procède à la résolution de l'identité en fonction de la valeur de EntityKey, qui correspond à une clé primaire dans la base de données. Si une requête retourne un objet avec un objet EntityKey qui existe déjà dans ObjectContext, aucun nouvel objet n'est créé. Si vous travaillez avec des colonnes de taille fixe dans la base de données et que vous rendez persistantes des valeurs plus courtes que la taille spécifiée dans la base de données, certaines bases de données rempliront des types de taille fixe par des espaces ou des zéros. SQL Server remplit les types de chaîne de taille fixe par des espaces de fin. Lorsque les types de taille fixe (tel que binary ou char) sont utilisés comme clés primaires, des problèmes de résolution de l'identité risquent de se produire.

Prenons l'exemple suivant. La table Product a une colonne de longueur fixe de taille 10 pour la clé primaire. Un objet Product avec une EntityKey AB100 est créé et ajouté au ObjectContext. Lorsque l'objet est enregistré dans la base de données, la clé est remplie avec des espaces de fin parce que la colonne a une taille fixe et que la valeur enregistrée est plus courte que la taille dans la base de données. La requête suivante pour un objet avec une EntityKey de AB100 retournera un objet avec une EntityKey différente (AB100 suivi par des espaces de fin) parce que SQL Server met en correspondance AB100 et la chaîne remplie. Entity Framework ne découpe pas et ne remplit pas les valeurs de propriétés. Le résultat est qu'un nouvel objet (avec EntityKeyAB100 suivi par des espaces de fin) est ajouté au ObjectContext.

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

Pour éviter ce comportement, vous pouvez effectuer l'une des actions suivantes :

  • Utilisez un type de longueur variable au lieu d'un type de longueur fixe dans la base de données.

  • Remplissez la valeur de EntityKey avec des espaces de fin ou des zéros sur le client. Vous pouvez utiliser la méthode PadRight pour remplir une chaîne par des espaces.

Clés d'entité et objets ajoutés

Lorsqu'une nouvelle entité est créée, Entity Framework définit la clé temporaire et la propriété IsTemporary sur true. Lorsque vous appelez la méthode SaveChanges, Entity Framework affecte une clé permanente et définit la propriété IsTemporary sur false.

Si la valeur de colonne correspondante est une identité générée dans la base de données, définissez l'attribut StoreGeneratedPattern de l'élément Property d'une entité dans le modèle de stockage, sur Identity. Lorsque les outils Entity Data Model génèrent un modèle de données depuis une source de données existante, l'attribut StoreGeneratedPattern est ajouté à chaque élément Élément Property (CSDL) qui représente une identité ou une colonne calculée dans la source de données. Entity Framework remplace la valeur de la propriété dans une clé temporaire par la valeur d'identité générée par la source de données après que SaveChanges a été appelé.

Les sections suivantes décrivent le processus interne qui permet de remplacer la clé temporaire par une clé permanente contenant les valeurs générées par le serveur :

  1. L'objet entité est construit.

    À ce stade, les propriétés de la clé ont toutes des valeurs par défaut, Null ou 0.

  2. Le nouvel objet est ajouté au ObjectContext en appelant la méthode AddObject sur ObjectContext ou ObjectSet, ou en ajoutant un objet à la collection d'objets sur la terminaison « many » de la relation.

    À ce stade, Entity Framework génère une clé temporaire utilisée pour stocker les objets dans le ObjectStateManager.

  3. SaveChanges est appelé sur ObjectContext.

    Une instruction INSERT est générée par Entity Framework et exécutée sur la source de données.

  4. Si l'opération INSERT réussit, les valeurs générées par le serveur sont réécrites dans ObjectStateEntry.

  5. ObjectStateEntry met à jour l'objet avec la valeur générée par le serveur.

  6. Lorsque AcceptChanges est appelé sur ObjectStateEntry, une EntityKey permanente est calculée à l'aide des nouvelles valeurs générées par le serveur.

    Dd283139.note(fr-fr,VS.100).gifRemarque :
    La méthode AcceptChanges est appelée automatiquement à la fin de l'exécution de SaveChanges ou lorsque la méthode SaveChanges est appelée avec la balise AcceptAllChangesAfterSave.

  7. ObjectStateManager remplace toutes les instances de la clé temporaire par la nouvelle clé permanente.

Valeurs de propriétés GUID

Entity Framework prend en charge des propriétés d'entité qui retournent un type Guid pour garantir l'unicité.

Entity Framework prend en charge les valeurs d'identité de type GUID générées par le serveur, mais le fournisseur doit pouvoir retourner la valeur d'identité générée par le serveur après l'insertion d'une ligne. SQL Server peut retourner le type GUID généré par le serveur via la clause OUTPUT, à partir de SQL Server 2005. Si un fournisseur ne prend pas en charge l'équivalent de la clause OUTPUT, générez des valeurs GUID pour les nouveaux objets sur le client. Pour ce faire, nous recommandons de gérer l'événement SavingChanges pour générer une nouvelle valeur GUID pour tout objet entité dans l'état Added. Pour plus d'informations, consultez Procédure : exécuter la logique métier lors de l'enregistrement de modifications (Entity Framework).

Lorsque vous générez ou mettez à jour un modèle de données avec l'Entity Data Model Wizard ou l'Update Model Wizard, les propriétés GUID des types d'entité sont générées automatiquement pour les colonnes de type uniqueidentifier dans la source de données. Une source de données peut également utiliser des colonnes binaires de 16 octets pour stocker des valeurs GUID. Étant donné que les outils génèrent une propriété binaire pour chaque colonne binaire dans la source de données, vous devez mettre à jour manuellement le mappage de telles colonnes aux propriétés GUID en modifiant le fichier .edmx. Pour plus d'informations, consultez How to: Map a GUID Property to a Binary Column.

Dans cette section

Procédure : créer un EntityKey (Entity Framework)

Voir aussi

Tâches

Procédure : créer un EntityKey (Entity Framework)

Autres ressources

Entity Data Model Tools