web-dev-qa-db-fra.com

DbContext est très lent lors de l'ajout et de la suppression

Lors de l'utilisation de DbContext dans un scénario de base de données, j'ai découvert que l'ajout et la suppression d'entités est très lent par rapport à ObjectContext. Si vous ajoutez 2000 entités et enregistrez les modifications à la fin, DbContext est 3 à 5 fois plus lent qu'ObjectContext (au fait: je sais que l'ajout d'une grande quantité d'entités serait mieux en utilisant SqlBulkCopy mais ce n'est pas le but). Si l'enregistrement des modifications après chaque ajout, DbContext est toujours presque deux fois plus lent. En ce qui concerne la suppression, cela empire encore: lors de l'enregistrement à la fin de tous les suppressions d'entités, DbContext est environ 18 fois plus lent qu'ObjectContext.

J'ai pris mon application de test hautement développée que j'utilise pour comparer les technologies d'accès à la base de données et une petite application console pour vérifier. Les deux ont montré de mauvais résultats pour l'ajout et la suppression d'entités à l'aide de DbContext. Voici les résultats de l'application console:

Inserting 2000 entities via DbContext saving changes at the end: 2164ms
Inserting 2000 entities via ObjectContext saving changes at the end: 457ms
Inserting 2000 entities via DbContext saving changes after each object addition: 8420ms
Inserting 2000 entities via ObjectContext saving changes after each object adding: 4857ms
Inserting 2000 entities via DbContext using a new DbContext for each object addition: 4018ms
Deleting 2000 entities via DbContext saving changes at the end: 4794ms
Deleting 2000 entities via ObjectContext saving changes at the end: 261ms
Deleting 2000 entities via DbContext saving changes after each object deletion: 25536ms
Deleting 2000 entities via ObjectContext saving changes after each object deletion: 2110ms

J'ai essayé d'utiliser EF 4.3 dans VC 2010 et EF 5.0 Beta 2 dans VS 11 avec presque les mêmes résultats. J'ai utilisé les modèles T4 fournis par le "Générateur d'entités POCO EF 4.x pour C #", le "Générateur EF 4.x DbContext pour C #" et le "Générateur EF 5.x DbContext pour C #".

Qu'est-ce qui ne va pas? Selon les résultats du test, je n'utiliserais jamais DbContext dans une application qui doit ajouter ou supprimer des entités (ce qui rend DbContext malheureusement inutilisable pour moi).

J'ai placé les applications de test de la console sur mon serveur Web: EF 4.3 DbContext Test , EF 5.0 DbContext Test

Toutes les idées/corrections sont appréciées.

46
Jürgen Bayer

Essayez d'ajouter ceci à vos tests DbContext:

dbContext.Configuration.AutoDetectChangesEnabled = false;

// Now do all your changes

dbContext.ChangeTracker.DetectChanges();
dbContext.SaveChanges();

et essayez de relancer vos tests.

Il y a eu un changement architectural dans l'API DbContext qui vérifie les changements dans les entités chaque fois que vous Add, Attach ou Delete quelque chose du contexte. Dans l'API ObjectContext, cette détection s'exécute uniquement lorsque vous avez déclenché SaveChanges. C'est une meilleure solution pour la plupart des scénarios courants, mais elle nécessite une gestion spéciale pour le traitement de masse des données.

91
Ladislav Mrnka

Dans EF6, vous pouvez désormais utiliser AddRange et RemoveRange on DbSet .

De à la documentation sur les liens:

Notez que si AutoDetectChangesEnabled est défini sur true (qui est la valeur par défaut), alors DetectChanges sera appelé une fois avant {l'ajout, la suppression} des entités et ne sera plus appelé. Cela signifie que dans certaines situations, {Ajouter, Supprimer} La plage peut être beaucoup plus efficace que d'appeler {Ajouter, Supprimer} plusieurs fois.

14
Andreas Warberg