La manière la plus rapide d’insérer dans Entity Framework
Concernant votre remarque dans les commentaires de votre question :
“…SavingChanges (pour chaque
enregistrement)…”
C’est la pire chose que vous puissiez faire ! Appeler SaveChanges() pour chaque enregistrement ralentit considérablement les insertions en masse. Je ferais quelques tests simples qui amélioreront très probablement les performances :
-
Appeler
SaveChanges()une seule fois après TOUS les enregistrements. -
Appeler
SaveChanges()après par exemple 100 enregistrements. -
Appeler
SaveChanges()après par exemple 100 enregistrements et libérer le contexte puis en créer un nouveau. -
Désactiver la détection des changements
Pour les insertions en masse, je travaille et expérimente avec un modèle comme celui-ci :
using (TransactionScope scope = new TransactionScope())
{
MyDbContext context = null;
try
{
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;
foreach (var entityToInsert in someCollectionOfEntitiesToInsert)
{
++count;
context = AddToContext(context, entityToInsert, count, 100, true);
}
context.SaveChanges();
}
finally
{
if (context != null)
context.Dispose();
}
scope.Complete();
}
private MyDbContext AddToContext(MyDbContext context,
Entity entity, int count, int commitCount, bool recreateContext)
{
context.Set<Entity>().Add(entity);
if (count % commitCount == 0)
{
context.SaveChanges();
if (recreateContext)
{
context.Dispose();
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
J’ai un programme de test qui insère 560 000 entités (9 propriétés scalaires, aucune propriété de navigation) dans la base de données. Avec ce code, cela fonctionne en moins de 3 minutes.
Pour les performances, il est important d’appeler SaveChanges() après “beaucoup” d’enregistrements (“beaucoup” étant environ 100 ou 1000). Cela améliore également les performances de libérer le contexte après SaveChanges et d’en créer un nouveau
(Réponse tronquée)