47
votes

When using DbContext in a database-first scenario I found out that adding and deleting entities is very slow compared to ObjectContext. If adding 2000 entities and saving the changes at the end, DbContext is 3 to 5 times slower than ObjectContext (btw.: I know that adding a large amount of entities would be better using SqlBulkCopy but that's not the point). If saving changes after each addition DbContext is still nearly two times slower. When it comes to deletion it even gets worse: When saving at the end of all entity removals, DbContext is around 18 times slower than ObjectContext.

I took my highly developed test application I use to compare database access technologies and a small console application to double check. Both showed bad results for adding and deleting entities using DbContext. Here are the results of the console application:

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

I tried using EF 4.3 in VC 2010 and EF 5.0 Beta 2 in VS 11 with nearly same results. I used the T4 templates provided by the "EF 4.x POCO Entity Generator for C#", the "EF 4.x DbContext Generator for C#" and the "EF 5.x DbContext Generator for C#".

What could be wrong? According to the test results I would never use DbContext in an application that has to add or delete entities (what makes DbContext unfortunately unusable for me).

I put the console test applications on my web server: EF 4.3 DbContext Test, EF 5.0 DbContext Test

Any ideas/corrections are appreciated.

2
Two references in addition to Ladislavs answer: stackoverflow.com/questions/5943394/… and stackoverflow.com/questions/5940225/…Slauma

2 Answers

93
votes

Try to add this to your DbContext tests:

dbContext.Configuration.AutoDetectChangesEnabled = false;

// Now do all your changes

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

and try to run your tests again.

There was some architectural change in DbContext API which checks changes in entities every time you Add, Attach or Delete anything from the context. In ObjectContext API this detection run only when you triggered SaveChanges. It is better solution for most common scenarios but it requires special handling for mass data processing.

14
votes

In EF6 you can now use AddRange and RemoveRange on DbSet.

From to the documentation on the links:

Note that if AutoDetectChangesEnabled is set to true (which is the default), then DetectChanges will be called once before {adding,deleting} any entities and will not be called again. This means that in some situations {Add,Remove}Range may perform significantly better than calling {Add,Remove} multiple times would do.