193 votes

Comment détacher des objets dans Entity Framework Code First ?

Il n'y a pas Detach(object entity) sur le DbContext .

Ai-je la possibilité de détacher des objets sur le code EF d'abord ?

328voto

Slauma Points 76561

C'est une option :

dbContext.Entry(entity).State = EntityState.Detached;

3 votes

Puis-je faire cela lorsque je récupère des objets qui renvoient un IQueryable ?

1 votes

@Lol coder : Je ne suis pas sûr de bien comprendre, mais entity doit être un objet matérialisé d'un type qui fait partie de vos classes de modèle (Personne, Client, Commande, etc.). Vous ne pouvez pas passer directement un IQueryable<T> dans la commande dbContext.Entry(...) . Est-ce la question que vous vouliez poser ?

0 votes

Quelle est la solution ? AsNoTracking() o Include() o dbContext.Entry(entity).State = EntityState.Detached;

187voto

Ladislav Mrnka Points 218632

Si vous voulez détacher un objet existant, suivez les conseils de @Slauma. Si vous voulez charger des objets sans suivre les changements, utilisez :

var data = context.MyEntities.AsNoTracking().Where(...).ToList();

Comme mentionné dans le commentaire, cela ne détachera pas complètement les entités. Elles sont toujours attachées et le chargement paresseux fonctionne mais les entités ne sont pas suivies. Ceci devrait être utilisé par exemple si vous voulez charger une entité uniquement pour lire des données et que vous ne prévoyez pas de les modifier.

3 votes

@Ladislav : C'est en effet probablement ce que Lol coder voulait dire. Je n'ai jamais utilisé cette méthode et n'y ai jamais pensé, bien que je charge souvent des listes d'objets et que je dispose du contexte en une seule fois, comme suit using(ctx){ return ctx....ToList(); } . Dans ce cas, l'utilisation de AsNoTracking() aurait beaucoup de sens car cela éviterait de remplir inutilement le contexte de l'objet. Je suppose que cela aurait probablement un avantage en termes de performances et de consommation de mémoire, notamment pour les grandes listes, non ?

1 votes

@Slauma : Oui, il y a un avantage en termes de performance. C'est d'ailleurs pour cela que cette méthode existe. L'utilisation de cette approche dans l'API ObjectContext est un peu plus compliquée.

2 votes

Est-ce que cela désactive le chargement paresseux ?

14voto

The Fabio Points 1497

Les deux réponses précédentes fournissent de bonnes instructions, mais elles risquent toutes deux de vous laisser avec les entités encore chargées dans le contexte de EF et/ou son Change Tracker.

Ce n'est pas un problème lorsque vous modifiez de petits ensembles de données, mais cela le devient lorsque vous en modifiez de grands. EF aurait une utilisation accrue de la mémoire et des ressources, ce qui à son tour réduirait les performances de la procédure puisqu'elle utilise plus de données/entités.

Les deux autres approches sont valables mais, dans ce cas, Microsoft recommande nettoyage du suivi des changements au lieu de détacher les entités individuellement

L'effacement du suivi des modifications sur la boucle de modification des données (qui modifie un morceau de données, par exemple) peut vous éviter ce problème.

context.ChangeTracker.Clear();

Cela déchargerait/détacherait toutes les entités et leurs références changeTracker du contexte, donc à utiliser avec précaution après que votre context.SaveChanges() .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X