Est-ce que l'obtention d'entités avec AsNoTracking() désactive l'appel automatique à DetectChanges ()?

J'ai appris à connaître ce concept de AsNoTracking(), DetectChanges(), et AutoDetectChangesEnabled très récemment. Je comprends que lors de l'extraction d'enregistrements de la base de données via Entity Framework avec AsNoTracking() utilisé, Entity Framework ne suit aucune modification sur ces enregistrements et la mise à jour de toute propriété de l'enregistrement récupéré échouera dans ce cas.

Ma question Est si les enregistrements sont récupérés de cette manière, cela entraînera-t-il également la désactivation de L'appel automatique à DetectChanges () ou doit-il être fait explicitement par réglage:

Context.Configuration.AutoDetectChangesEnabled = false;

Veuillez également me faire savoir quel impact (en termes de performance) a-t-il si les deux actions sont effectuées lors de la récupération des données strictement à des fins de lecture seule:

Context.Configuration.AutoDetectChangesEnabled = false;
Context.Set<T>().AsNoTracking();
23
demandé sur Alex Angas 2014-01-08 10:41:51

2 réponses

Cela entraînera-t-il également la désactivation de L'appel automatique à DetectChanges ()

Non, ce ne sera pas le cas. mais vous devez réaliser que AsNoTracking et DetectChanges n'ont rien à voir les uns avec les autres (à part faire partie de EF). Les objets récupérés avec AsNoTracking ne seront jamais détectés de toute façon, que AutoDetectChanges soit activé ou non. De plus, AsNoTracking fonctionne au niveau DbSet, AutoDetectChangesEnabled au niveau du contexte. Il serait mauvais d'avoir une méthode DbSet affecter l'ensemble du contexte.

Ou ça [paramètre AutoDetectChangesEnabled] doit être fait explicitement

Eh bien, vous ne devriez probablement pas désactiver AutoDetectChanges. Si vous le faites, vous devez savoir ce que vous faites.

Quel impact (en termes de performance) a-t-il si les deux actions sont effectuées

Comme dit, ils ne sont pas liés. Ils peuvent à la fois améliorer les performances à leur manière.

  • AsNoTracking est génial si vous voulez récupérer des données en lecture seule. Il n'a pas d'effets secondaires (comme dans son l'effet est clair)
  • Le réglage AutoDetectChangesEnabled = false arrête les appels automatiques de DetectChanges (qui peuvent être nombreux), mais il a des effets secondaires dont vous devez être conscient. De Lerman & Miller Livre DbContext :

    Travailler quand DetectChanges doit être appelé n'est pas aussi trivial que peuvent apparaître. L'équipe Entity Framework vous recommande fortement swap uniquement pour appeler manuellement DetectChanges si vous rencontrez des problèmes de performances. Il est également recommandé d'opter uniquement automatique DetectChanges pour les sections de code peu performantes et pour le réactiver une fois que la section en question a terminé l'exécution.

27
répondu Gert Arnold 2014-01-08 21:34:54

Nous avons constaté que le réglage de AutoDetectChangesEnabled = false peut avoir des impacts substantiels (c.-à-d. facteur de 10) sur les performances.

Background : Notre système est entièrement composé D'objets de modèle EF qui utilisent des proxies de détection de changement. C'est-à-dire que tous nos champs de base de données et propriétés relationnelles sont déclarés comme virtuels. Nous avons également un modèle d'objet relativement profondément structuré. C'est l'objet A contient un ensemble de l'objet B, qui à son tour contient un ensemble d'Objet de C, etc. Nous avons observé que l'instanciation d'un le nombre non trivial (> 100) de ces objets via une requête EF/LINQ est coûteux. Par exemple, dans un cas, l'instanciation de 250 objets a nécessité environ 2 secondes. Nous avons également observé que l'instanciation de la même structure, mais l'utilisation d'objets anonymes à la place nécessitait environ 25 ms. enfin, nous avons observé que si nous définissons AutoDetectChangesEnabled = false, nous pourrions utiliser la requête instanciant les objets du modèle EF et la matérialisation à nouveau était d'environ 25 ms.

Donc, au moins pour nous, il y avait des gains énormes à faire en le définissant faux. Nous utilisons un modèle D'Unité de travail, et nous indiquons explicitement si l'Unité de travail est en lecture seule ou non. Pour une unité de travail en lecture seule, la définition de AutoDetectChangesEnabled = false est parfaitement sûre, car il n'y aura jamais de modifications. En fait, nous avons ajouté ce changement à notre système deux ans après notre version initiale (il y avait donc beaucoup, beaucoup d'unités de travaux préexistantes dans le code) et le changement n'a rien cassé du tout, et a considérablement amélioré les performances.

Nous avons également expérimenté avec AsNoTracking() et a constaté qu'il nous a donné essentiellement aucune augmentation de performance du tout. Si je comprends bien, une requête avec AsNoTracking() signifie que les objets ne seront pas placés dans la carte d'identité, ce qui forcera EF à récupérer l'objet du disque s'il est référencé plus d'une fois dans le contexte (par exemple dans différentes requêtes). Il y a donc un inconvénient potentiel à AsNoTracking().

Détails De Mise En Œuvre:

  • Nous avons une sous-classe de DBContext qui fournit une grande partie de l'infrastructure pour notre unité de travail
  • notre unité de travail est essentiellement un wrapper léger autour du contexte
  • Lorsqu'une unité de travail est allouée (généralement dans un bloc en utilisant), elle reçoit l'un de ces contextes par injection (nous utilisons Castle/Windsor)
  • lors de l'initialisation, l'Unité de travail appelle une méthode dans le contexte dans laquelle AutoDetectChangesEnabled prend la valeur false
  • Actuellement, nous faisons ceci Tout le temps parce que nous utilisons toujours des proxies de détection de changement et ils ne le font pas nécessite AutoDetectChangesEnabled
  • auparavant, nous ne le faisions que pour les unités de travail "en lecture seule", car si rien n'est modifié dans un UoW, il n'est pas nécessaire de détecter les changements (lorsque nous avons alloué une unité de travail, nous indiquons explicitement si elle est en lecture seule ou non)
  • -
18
répondu Terry Coatta 2015-09-12 17:11:20