I am using AutoMapper to map objects from a legacy database to a new database declared in EF code first:
StartTimer("Map Customers");
var mfpCustomers = Mapper.Map<IEnumerable<LegacyDataModel.Customer>, IEnumerable<Customer>>(
legacyEntities.Customers.Include(p => p.Demographics).ToList());
StopAndPrintTimer("Map Customers");
StartTimer("Iterate Customers");
foreach (var p in mfpCustomers)
{
db.Customers.Add(p);
}
StopAndPrintTimer("Iterate Customers");
The for each is what takes the most time. I would like to map directly to a DbSet(db.Customer), instead of doing a foreach over db.Customers.Add(p);. I haven’t figured out how to do this though as there is nothing like an AddRange method designed specifically for adding large numbers of objects. I know how to do these types of transformations with set based techniques in SQL, but that is an insane amount of typing because the intellisense doesn’t work that great in those scenarios in SSMS.
This code doesn’t need to be super fast, but having to wait a full minute every time I seed the database is making development hard(and it does need to be reseeded often due to rapid development of the new database). Note also that since this is the seed method, I don’t mind completely replacing the existing Customers(since there are none). So it doesn’t need to behave like AddRange in that respect, as I’m really just creating a new collection.
Any ideas on how I can improve the performance here?
Any ideas on how I can map the entire collection directly into the DbSet without doing a foreach on every instance?
Each time you call db.Customers.Add(p) EF is making a DetectChanges call to see if anything in your entity graph has changed. This helps make things work as expected when Add is called after making changes to other entities. However, DetectChanges can get slow if there are a lot of entities in the context–it has O(n) time on the number of entities. So in cases like you have it can make a big difference if you temporarily turn of these automatic calls to DetectChanges. For example:
You can find more details here:
http://blogs.msdn.com/b/adonet/archive/2011/02/06/using-dbcontext-in-ef-feature-ctp5-part-12-automatically-detecting-changes.aspx