I am trying to enhance the performance of writing thousands of rows to a db using EF. I have found that the speed of SaveChanges() degrades over time within a single context, and disposing and recreating the context after n inserts can help this.
using(Context context = new Context())
{
for(int i = 0; i < numberOfLines; i++)
{
context.Collection.AddObject(line);
if (i % 100 == 0)
{
context.SaveChanges()
// Here I would like to call dispose on context and then create a new one
}
}
}
Of course, I need to use using or do something similar because there is a lot more going on and I need to ensure that dispose will be called if an exception gets thrown at any time.
Any ideas? I know I can declare the context outside of a try block, and then have a finally with context.Dispose(). I obviously don't want to do that though.
EDIT: I realized the code snippet I posted doesn't totally show why I am trying to do this. The for loop calls context.SaveChanges() in other spots outside of the IF statement. So when the IF evaluates to true, I've called SaveChanges() a number of times already.
It sounds like you basically want to process a collection in batches. That's simple using MoreLINQ (also on NuGet):
foreach (var batch in dataToUpload.Batch(100))
{
using (var context = new Context())
{
foreach (var item in batch)
{
...
}
context.SaveChanges();
}
}
Aside from anything else, that describes what you're trying to achieve (IMO) much more clearly than using one loop with a check for i % 100
in it.
(Original link to http://morelinq.googlecode.com is no longer valid, replaced with current GitHub link)
See more on this question at Stackoverflow