J'ai appris à connaître ce concept de AsNoTracking()
, DetectChanges()
et AutoDetectChangesEnabled
très récemment. Je comprends que lors de la récupération des enregistrements de la base de données via Entity Framework avec AsNoTracking()
utilisé, Entity Framework ne suit pas les modifications apportées à ces enregistrements et la mise à jour de toute propriété de l'enregistrement récupéré échouera dans ce cas.
Ma question est de savoir 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 cela doit-il être fait explicitement en définissant:
Context.Configuration.AutoDetectChangesEnabled = false;
Veuillez également me faire savoir quel impact (en termes de performances) cela 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();
cela entraînera-t-il également la désactivation de l'appel automatique à DetectChanges ()
Non, ce ne sera pas le cas. Mais vous devez comprendre que AsNoTracking
et DetectChanges
n'ont rien à voir l'un avec l'autre (à part faire partie d'EF). Les objets récupérés avec AsNoTracking
ne seront de toute façon jamais détectés, que AutoDetectChanges soit activé ou non. En outre, AsNoTracking
fonctionne au niveau DbSet
, AutoDetectChangesEnabled
au niveau du contexte. Il serait mauvais qu'une méthode DbSet
affecte l'ensemble du contexte.
ou que le [réglage
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 performances) a-t-il si les deux actions sont réalisées
Comme je l'ai dit, ils ne sont pas liés. Ils peuvent tous deux améliorer les performances à leur manière.
AsNoTracking
est idéal si vous souhaitez récupérer des données en lecture seule. Il n'a pas d'effets secondaires (comme dans: son effet est clair)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. Extrait du livre de Lerman & Miller DbContext:
Déterminer quand DetectChanges doit être appelé n'est pas aussi trivial qu'il y paraît. L'équipe Entity Framework vous recommande fortement de ne passer à l'appel manuel de DetectChanges que si vous rencontrez des problèmes de performances. Il est également recommandé de ne désactiver les DetectChanges automatiques que pour les sections de code peu performantes et de le réactiver une fois que la section en question a terminé son exécution.
Nous avons constaté que la définition de AutoDetectChangesEnabled = false
Peut avoir des impacts de performance substantiels (c'est-à-dire un facteur 10).
Contexte: Notre système est entièrement composé d'objets de modèle EF qui utilisent des proxys de détection de changement. Autrement dit, tous nos champs de base de données et nos propriétés relationnelles sont déclarés comme virtuels. Nous avons également un modèle objet relativement profondément structuré. Autrement dit, l'objet A contient un ensemble d'objets B, qui à leur tour contiennent un ensemble d'objets C, etc. Nous avons observé que l'instanciation d'un nombre non trivial (> 100) de ces objets via une requête EF/LINQ coûte cher. 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 à la place d'objets anonymes nécessitait environ 25 ms. Enfin, nous avons observé que si nous définissions AutoDetectChangesEnabled = false
, Nous pourrions utiliser à nouveau la requête instanciant les objets du modèle EF et la matérialisation é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, le réglage de AutoDetectChangesEnabled = false
Est parfaitement sûr, car il n'y aura jamais de changement. En fait, nous avons ajouté cette modification à notre système deux ans après notre version initiale (il y avait donc de nombreuses unités préexistantes dans le code) et la modification n'a rien cassé du tout et a considérablement amélioré les performances.
Nous avons également expérimenté AsNoTracking()
et nous avons constaté qu'il ne nous apportait pratiquement aucune augmentation des performances. 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 à nouveau l'objet à partir du disque s'il est référencé plusieurs fois dans le contexte (par exemple dans différentes requêtes). Il y a donc un inconvénient potentiel à AsNoTracking()
.
Détails d'implémentation: