0

Context:

I'm doing a migration from Access to SQL Server. It's a complex'ish migration and ran fairly often -- so I integrated it into the website so the user can do it on their own occasionally, if needed.

Weirdness:

So I initially decided to go with one context doing regular SaveChanges() at the end of each area.

When it got to ~ 60k inserts, it took a VERY long time to save.

Ok, I thought, I'll just run SaveChanges after each entry. It took a long time. Obscenely long.

Ok, so I decided to try SaveChangesAsync and simply couldn't get it to work. I was willing to give this one area it's own Dbcontext and just let it save in the background and before the finale I would await it. Couldn't get that to work. Initially it'd throw an error and then it simply wouldn't save the data.

Ok, so the next step was to try giving this method its own DbContext. Worked like a DREAM.

I then gave each method (about 13 in all) their own DbContext. Everything was very fast.

So my question is: what's the difference between one DbContext, with 13 SaveChanges() calls, and 13 DbContexts with 13 calls to SaveChanges()?

Is there something left behind after you run SaveChanges() that I could clean? Or should I simply just go with many DbContext's? I was simply trying to avoid opening a new connection each and every time to shave off that little bit of time but it's not really a big deal but I'm still lacking in understanding why this is the case. Can someone educate me?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Kenny Mann
  • 881
  • 10
  • 28
  • 1
    You probably need to understand the DbContext lifetime, change tracker and AsNoTracking – ErikEJ Apr 19 '20 at 15:58
  • Funny you mention that because while dorking around with SignalR I saw a link that explains the lifetime of various aspects of that AND linked to DbContext and I thought "eh, how much could that ever really effect me?" #LessonLearned – Kenny Mann Apr 19 '20 at 19:24

1 Answers1

3

Is there something left behind after you run SaveChanges() that I could clean?

Yes. The Change Tracker. By default the DbContext will retain all loaded entities, and in this scenario that makes both loading additional entities and identifying changed entities progressively more expensive.

So use multiple DbContext instances, or detach all the entities after SaveChanges(), as in the answer here How do I clear tracked entities in entity framework;

David Browne - Microsoft
  • 80,331
  • 6
  • 39
  • 67
  • Thanks! After something like 250k entities, it was dog slow compared to my original code which ran in a console and was more sloppy, which was like 3 minutes to do the whole thing. I was very confused why my supposedly more efficient code was slower. You've cleared it up, thanks much! – Kenny Mann Apr 19 '20 at 16:57