Reputation: 52952
I'm looking for why this might be or ways that I can speed it up.
I essentially construct an object with code like this
(pseudo code)
Person p = new Person();
Address a = new Address() { ... properties set here ... };
Employer e = new Employer() { ... properties set here ... };
// etc.
p.Employer = e;
p.Address = a;
//etc.
And finally:
_context.Person.Add(p);
When I profile the code, the construction of the person takes 0ms it's lightning fast. When I add the person the context however, it takes about 1500ms. Could it be to do with constraint checking? The database is quite large although it's not loaded into memory or anything so at the point it does the Add
it shouldn't have touched the database.
Only when I do _context.SaveChanges()
should it be written.
Any suggestions to improve speed?
Edit: Benchmark is done like this: (sw is a new Stopwatch()
)
sw.Restart();
context.Person.Add(p);
Console.WriteLine("Person added to context: " + sw.ElapsedMilliseconds + "ms");
Edit 2: The plot thickens.
As I'm loading in a huge number of people and adding them into the database, one of the first operations I do is see if the person already exists in the database. For speed reasons I pull a full list of Person.PersonId into a hashtable and check them for each record to be inserted.
If the person already exists in the list, I pull them out of the database. This takes ~5ms and I don't do anything with the data (as I haven't written that part yet) and just skip to the next one.
However when it reaches the new entries that are being added to the context, it is that line that causes a massive slowdown. Here's the code:
matchPerson = _context.Person.SingleOrDefault(c => c.PersonId == intPersonId);
So it pulls the person out of the database if they are already in it via the 0ms hashtable check (it's instant).
It takes ~5ms to do it.
If I do the above _context.Add
when this line is present, it goes super slow. If I comment it out, it takes about 40ms and with each added record increases (so after 2,000 records it takes about 200ms).
There's no link I can see between the two lines, so perhaps the context query resets the state of the context and slows down the next operation?
Upvotes: 2
Views: 459
Reputation: 8656
As requested in the comments (in case this isn't closed a duplicate), the slowdown was related to automatic change detection, which is on by default in the DbContext
API.
To disable automatic change detection:
context.Configuration.AutoDetectChangesEnabled = false;
A much more complete/full description (which I certainly can't better here) can be found in this accepted answer:
Why is inserting entities in EF 4.1 so slow compared to ObjectContext?
Upvotes: 1