title: Entity Framework 6 DbSet AddRange vs IDbSet Add - How Can AddRange be so much faster?
body: <p>I was playing around with Entity Framework 6 on my home computer and decided to try out inserting a fairly large amount of rows, around 430k. </p>
  
  <p>My first try looked like this, yes I know it can be better but it was for research anyway:</p>
  
  <pre><code>var watch = System.Diagnostics.Stopwatch.StartNew();
  foreach (var event in group)
  {
      db.Events.Add(event);
      db.SaveChanges();
  }
  
  var dbCount = db.Events.Count(x =&gt; x.ImportInformation.FileName == group.Key);
  
  if (dbCount != group.Count())
  {
      throw new Exception("Mismatch between rows added for file and current number of rows!");
  }
  
  watch.Stop();
  Console.WriteLine($"Added {dbCount} events to database in {watch.Elapsed.ToString()}");
  </code></pre>
  
  <p>Started it in the evening and checked back when I got home from work. This was the result:</p>
  
  <p><a href="https://i.stack.imgur.com/UBZoz.png" rel="noreferrer"><img src="https://i.stack.imgur.com/UBZoz.png" alt="enter image description here"></a></p>
  
  <p>As you can see 64523 events were added in the first 4 hours and 41 minutes but then it got a lot slower and the next 66985 events took 14 hours and 51 minutes. I checked the database and the program was still inserting events but at an extremely low speed. I then decided to try the "new" <a href="https://msdn.microsoft.com/en-US/library/system.data.entity.dbset.addrange(v=vs.113).aspx" rel="noreferrer">AddRange</a> method for DbSet.</p>
  
  <p>I switched my models from <code>IDbSet</code> to <code>DbSet</code> and replaced the <code>foreach</code> loop with this:</p>
  
  <pre><code>db.Events.AddRange(group);
  db.SaveChanges();
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/E07gI.png" rel="noreferrer"><img src="https://i.stack.imgur.com/E07gI.png" alt="enter image description here"></a></p>
  
  <p>I could now add 60k+ events in around 30 seconds. It is perhaps not <a href="https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx" rel="noreferrer">SqlBulkCopy</a> fast but it is still a huge improvement. What is happening under the hood to achieve this? I thought I was gonna check <code>SQL Server Profiler</code> tomorrow for queries but It would be nice with an explanation what happens in code as well.</p>