FreeVice
FreeVice

Reputation: 2697

EF SaveChanges optimisation?

Why DbContext ctx disposing after each SaveChanges() perform more quickly?

First sample:

var ctx = new DomainContext(); 
foreach (var item in deals)
        {
            DealsOfReutersAddition newDealAddition =
                        new DealsOfReutersAddition
                        {
                            DealsOfReutersId = item.DealsOfReutersId,
                            DealDate = DateTime.Parse(item.DateConfirmed ?? "01 01 01", new CultureInfo("en-US")),
                        };
            ctx.DealsOfReutersAdditions.Add(newDealAddition);
            ctx.SaveChanges();
        }

ctx.Dispose();

Second sample:

foreach (var item in deals)
        {
            DealsOfReutersAddition newDealAddition =
                        new DealsOfReutersAddition
                        {
                            DealsOfReutersId = item.DealsOfReutersId,
                            DealDate = DateTime.Parse(item.DateConfirmed ?? "01 01 01", new CultureInfo("en-US")),
                        };
            var ctx = new DomainContext(); 
            ctx.DealsOfReutersAdditions.Add(newDealAddition);
            ctx.SaveChanges();
            ctx.Dispose();
        }

On 1000 rows second sample estimated at 8 seconds aganist of 140 seconds in first. Any way to clean ctx instead recreating?

Upvotes: 3

Views: 373

Answers (1)

Corey Adler
Corey Adler

Reputation: 16137

Along the lines of what @JensKloster was saying in the comments, you definitely don't want to call SaveChanges every single time in the loop. But I would actually resist the temptation of putting it outside of the loop. As the number of objects being tracked by the context gets higher and higher, more memory will be used up, and it will make saving incrementally slow.

My solution for you, then, is to have a running counter in the loop to determine when you would do the save:

int numberOfRecords = 0;
using(var ctx = new DomainContext())
{
  foreach (var item in deals)
          {
              DealsOfReutersAddition newDealAddition =
                          new DealsOfReutersAddition
                          {
                              DealsOfReutersId = item.DealsOfReutersId,
                              DealDate = DateTime.Parse(item.DateConfirmed ?? "01 01 01", new CultureInfo("en-US")),
                          };

              ctx.DealsOfReutersAdditions.Add(newDealAddition);

              numberOfRecords++;
              if(numberOfRecords % 500 == 0) //Saves after every 500 rows.
              {
                ctx.SaveChanges();
              }
           }
}

Upvotes: 4

Related Questions