Le même sujet a été abordé ici il y a 8 mois : Comment accélérer DbSet.Add() ? . Aucune solution n'a été proposée à part l'utilisation de SqlBulkCopy qui n'est pas acceptable pour nous. J'ai décidé d'en parler une fois de plus en espérant qu'il y ait de nouvelles pensées et idées autour de ce problème et que d'autres solutions de contournement soient proposées. En tout cas, je suis simplement curieux de savoir pourquoi cette opération prend autant de temps à s'exécuter.
Le problème est le suivant : je dois mettre à jour 30K entités dans une base de données (EF 4.1, POCO). Le type d'entité est assez simple, contenant un Id entier + 4 autres propriétés entières, sans relation avec d'autres types. 2 cas :
-
tous sont de nouveaux enregistrements. Exécuter context.Entities.Add(entity) un par un pour chaque entité prend 90 secondes avec Cntx.Configuration.AutoDetectChangesEnabled=false (la valeur vraie le fait tourner indéfiniment). Ensuite, SaveChanges ne prend qu'une seconde. Autre approche : l'attacher au contexte comme ceci prend les mêmes 90 secondes :
Cntx.Entities.Attach(entity); Cntx.Entry(entity).State = EntityState.Added;
-
tous sont des enregistrements existants avec quelques modifications. Dans ce cas, il ne faut que quelques millisecondes pour l'attacher à un contexte de données existant comme ceci :
Cntx.Entities.Attach(entity); Cntx.Entry(entity).State = EntityState.Modified;
Vous voyez la différence ?
Qu'est-ce qui se passe derrière la scène de la méthode Add et qui fait qu'elle fonctionne si incroyablement lentement ?