Résolution d'identité, gestion des états et suivi des modifications (Entity Framework)
L'objet ObjectContext représente un conteneur pour les objets en mémoire. Le contexte de l'objet, avec l'aide d'autres classes et interfaces, gère l'identité d'un objet, son état, les valeurs d'origine et actuelles des propriétés de l'objet, et assure le suivi des modifications apportées à chaque objet contenu dans le cache. Pour plus d'informations sur l'attachement d'objets au contexte de l'objet, consultez Attachement et détachement d'objets (Entity Framework). Cette rubrique expose la manière dont le contexte de l'objet gère le suivi des modifications, la résolution d'identité et la gestion d'état.
Suivi des modifications
Les informations de suivi des modifications pour le graphique d'objet sont stockées dans des objets ObjectStateEntry, créés par ObjectContext pour chaque objet attaché. Les objets ObjectStateEntry stockent les informations suivantes pour les entités :
EntityKey qui détermine l'identité d'une entité.
EntityState de l'objet.
Informations sur les objets connexes
Nom du jeu d'entités.
Propriétés CurrentValues et OriginalValues des propriétés de l'entité (les objets dans un état Added n'ont pas de valeurs d'origine).
Noms des propriétés modifiées de l'entité.
Pour savoir si la valeur d'une propriété a été modifiée entre les appels à la méthode SaveChanges, interrogez la collection de noms de propriété modifiés retournée par la méthode GetModifiedProperties.
Remarque : |
---|
Si vous utilisez les entités POCO sans proxys de suivi des modifications, vous devez appeler DetectChanges avant d'appeler GetModifiedProperties. |
Lorsqu'une entité est détachée, l'objet ObjectStateEntry correspondant est supprimé du contexte de l'objet.
Les objets ObjectStateEntry sont gérés par ObjectStateManager. On compte une instance de ObjectStateManager par contexte de l'objet. Pour obtenir l'objet ObjectStateEntry pour l'entité spécifiée, utilisez l'une des méthodes suivantes sur ObjectStateManager : TryGetObjectStateEntry, GetObjectStateEntry ou GetObjectStateEntries.
Le contexte de l'objet est informé des modifications apportées aux propriétés des entités et des objets de proxy de suivi des modifications POCO générés par Entity Framework à mesure qu'elles interviennent et met à jour l'état des objets et les valeurs des propriétés dans ObjectStateEntry. Le modèle de rapport de modifications implique de signaler une modification en attente d'une propriété, de définir la propriété, puis de signaler la fin de la modification en utilisant l'interface IEntityChangeTracker. L'objet ObjectStateEntry ne gère pas de la même façon les entités POCO sans objets proxy de suivi des modifications et les objets de type complexe. Pour plus d'informations, consultez Suivi des modifications dans les entités POCO (Entity Framework).
Le contexte de l'objet utilise les informations dans les objets ObjectStateEntry pour rendre des données persistantes dans la source de données. Pour plus d'informations, consultez Enregistrement des modifications et gestion de l'accès concurrentiel (Entity Framework) et Procédure : exécuter la logique métier lors de l'enregistrement de modifications (Entity Framework).
Résolution d'identité et options de fusion
Entity Framework ne gère qu'une seule instance d'un objet avec une clé d'entité spécifique dans le cache. Les objets EntityKey sont des objets immuables qui représentent l'identité d'objet. Les clés d'entité sont utilisées pour assurer la résolution d'identité dans le contexte de l'objet. Pour plus d'informations, consultez Utilisation des clés d'entité (Entity Framework). Si une entité ayant la même identité fait déjà l'objet d'un suivi, les données en provenance de la source de données et les données déjà présentes dans le gestionnaire d'état sont fusionnées en fonction de l'option MergeOption de la requête.
Le tableau suivant présente les options de fusion possibles :
Membre | Description |
---|---|
Les objets qui n'existent pas dans le contexte de l'objet ne sont pas attachés au contexte. Si un objet est déjà présent dans le contexte, les valeurs actuelles et d'origine des propriétés de l'objet dans l'entrée ne sont pas remplacées par les valeurs de la source de données. L'état de l'entrée de l'objet et l'état des propriétés de l'objet dans l'entrée ne changent pas. AppendOnly est l'option de fusion par défaut. |
|
Les objets qui n'existent pas dans le contexte de l'objet ne sont pas attachés au contexte. Si un objet est déjà présent dans le contexte, les valeurs actuelles et d'origine des propriétés de l'objet dans l'entrée sont remplacées par les valeurs de la source de données. L'état de l'entrée de l'objet a la valeur Unchanged, aucune propriété n'est marquée comme modifiée. |
|
Les objets qui n'existent pas dans le contexte de l'objet ne sont pas attachés au contexte. Si l'état de l'entité est Unchanged, les valeurs actuelles et d'origine dans l'entrée sont remplacées par les valeurs de la source de données. L'état de l'entité reste Unchanged et aucune propriété n'est marquée comme modifiée. Si l'état de l'entité est Modified, les valeurs actuelles des propriétés modifiées ne sont pas remplacées par les valeurs de la source de données. Les valeurs d'origine des propriétés non modifiées sont remplacées par les valeurs de la source de données. Dans le .NET Framework version 4, Entity Framework compare les valeurs actuelles des propriétés non modifiées avec les valeurs retournées par la source de données. Si les valeurs ne sont pas identiques, la propriété est marquée comme modifiée. Dans le .NET Framework version 3.5 SP1, Entity Framework ne marque pas la propriété comme modifiée, même si la valeur dans la source de données est différente. Seules les propriétés modifiées sont rendues persistantes dans la source de données lorsque vous appelez SaveChanges. Pour préserver le comportement de la version 3.5 SP1, attribuez à la propriété UseLegacyPreserveChangesBehavior la valeur true. L'option PreserveChanges peut être utilisée pour résoudre les exceptions d'accès concurrentiel optimiste tout en préservant les modifications dans le contexte local. Pour plus d'informations, consultez Enregistrement des modifications et gestion de l'accès concurrentiel (Entity Framework). |
|
Les objets sont maintenus dans un état Detached et ne sont pas suivis dans l'objet ObjectStateManager. Toutefois, les entités générées par Entity Framework et les entités POCO avec proxys conservent une référence au contexte de l'objet pour faciliter le chargement des objets connexes. |
État des entités
Le contexte de l'objet doit connaître l'état d'un objet pour enregistrer les modifications dans la source de données. Les objets ObjectStateEntry stockent les informations de l'objet EntityState. Les méthodes SaveChanges de l'objet ObjectContext traitent les entités attachées au contexte et mettent à jour la source de données en fonction de l'objet EntityState de chaque objet. Pour plus d'informations, consultez Création, ajout, modification et suppression d'objets (Entity Framework). Le tableau suivant présente les différents états possibles d'un objet :
Membre | Description |
---|---|
Added |
L'objet est nouveau, a été ajouté au contexte de l'objet et la méthode SaveChanges n'a pas été appelée. Une fois les modifications enregistrées, l'état de l'objet passe à Unchanged. Les objets dans l'état Added ne possèdent pas de valeurs d'origine dans ObjectStateEntry. |
L'objet a été supprimé du contexte de l'objet. Une fois les modifications enregistrées, l'état de l'objet passe à Detached. |
|
Detached |
L'objet existe mais ne fait pas l'objet d'un suivi. Une entité est dans cet état juste après avoir été créée et avant d'être ajoutée au contexte de l'objet. Une entité est également dans cet état après avoir été supprimée du contexte en appelant la méthode Detach ou si elle est chargée à l'aide d'un objet NoTrackingMergeOption. Aucune instance de ObjectStateEntry n'est associée aux objets dans l'état Detached. |
Modified |
L'une des propriétés scalaires de l'objet a été modifiée et la méthode SaveChanges n'a pas été appelée. Dans les entités POCO sans proxys de suivi des modifications, l'état des propriétés modifiées passe à Modified lorsque la méthode DetectChanges est appelée. Une fois les modifications enregistrées, l'état de l'objet passe à Unchanged. |
Unchanged |
L'objet n'a pas été modifié depuis son attachement au contexte ou depuis le dernier appel de la méthode SaveChanges. |
L'état des objets à l'intérieur d'un contexte d'objet est géré par l'objet ObjectStateManager. Pour déterminer l'état d'un objet, appelez l'une des méthodes ObjectStateManager suivantes : TryGetObjectStateEntry, GetObjectStateEntry ou GetObjectStateEntries. La propriété State de l'objet ObjectStateEntry définit l'état de l'objet.