(A) This version is slow... duration is measured in multiple minutes
- DB is a typical EF Data Context to a SQL Serve database
AA_Words_100is a simple SQL Server table which is added to the EF designerDB.AA_Words_100.Addis called ~3,000 times (confirmed via debugging with counter variables)- I have confirmed that >99% of the runtime is inside the inner loop
XCampaignis aDictionary<string, Dictionary<string, _Word>>where _Word is a trivial non-EF object.
foreach (var XCampaign in Words100)
foreach (var KVP in XCampaign.Value)
DB.AA_Words_100.Add(KVP.Value.To_AA_Word_100());
DB.SaveChanges();
(B) This version is fast... - .Add() is simply commented out to narrow the scope
var iTemp = 0;
foreach (var XCampaign in Words100)
foreach (var KVP in XCampaign.Value)
iTemp++;
DB.SaveChanges();
(C) This version is fast. I simply fill up a List before calling DB.AddRange(...)
var LIST_WordsToAdd = new List<AA_Words_100>();
foreach (var XCampaign in Words100)
{
foreach (var KVP in XCampaign.Value)
{
LIST_WordsToAdd.Add(KVP.Value.To_AA_Word_100());
}
DB.AA_Words_100.AddRange(LIST_WordsToAdd);
}
DB.SaveChanges();
(D) Documentation
According to DbContext.Add documentation
Begins tracking the given entity, and any other reachable entities that are not already being tracked, in the Added state such that they will be inserted into the database when SaveChanges() is called.
In particular, when SaveChanges() is called.
I recently migrated to EF from Linq-to-SQL in this application. Linq-to-SQL did not have this problem.
What reason could there be for the DB.AA_Words_100.Add(...) command being so slow?
Thank you!
#Update - To_AA_Word_11() Code
public AA_Words_100 To_AA_Word_100()
{
var W = new AA_Words_100();
W.Word = Word;
W.Word_Clean = Word.Replace("'", "");
W.PhraseCount = PhraseCount;
W.Clicks = Clicks;
W.Impressions = Impressions;
W.SalesAmt = SalesAmt;
W.SalesOrders = SalesOrders;
W.SalesUnits = SalesUnits;
W.Spend = Spend;
W.Campaign = Campaign;
return W;
}
var count = DB.AA_Word_100.Local.Count()and see how many objects it is tracking. Every time you add an entity to a DbSet there is a cost as EF assesses it against everything it is already tracking. The more entities (and related entities) it tracks, the bigger this cost gets. For bulk-like operations you will want fresh DbContexts or consider non-EF DbContext approaches.AddRangewhen inserting numerous items.