我正在使用實體框架來構建數據庫。有兩種模式; 工作人員 and 技能。每個工人有零個或多個技能。我最初從某個CSV文件中將這些數據讀入內存,並將其存儲在名爲allWorkers
的字典中。接下來,我將數據寫入到數據庫這樣的:使用實體框架插入很多行非常慢
// Populate database
using (var db = new SolverDbContext())
{
// Add all distinct skills to database
db.Skills.AddRange(allSkills
.Distinct(StringComparer.InvariantCultureIgnoreCase)
.Select(s => new Skill
{
Reference = s
}));
db.SaveChanges(); // Very quick
var dbSkills = db.Skills.ToDictionary(k => k.Reference, v => v);
// Add all workers to database
var workforce = allWorkers.Values
.Select(i => new Worker
{
Reference = i.EMPLOYEE_REF,
Skills = i.GetSkills().Select(s => dbSkills[s]).ToArray(),
DefaultRegion = "wa",
DefaultEfficiency = i.TECH_EFFICIENCY
});
db.Workers.AddRange(workforce);
db.SaveChanges(); // This call takes 00:05:00.0482197
}
最後db.SaveChanges();
需要五分鐘來執行,這我覺得是太長了。我跑SQL Server事件探查器作爲呼叫正在執行,並且基本上是我發現了數以千計的電話給:
INSERT [dbo].[SkillWorkers]([Skill_SkillId], [Worker_WorkerId])
VALUES (@0, @1)
有被添加到SkillWorkers
16027行,這是一個相當數量的數據,但沒有任何巨大手段。有什麼方法可以優化這段代碼,所以不需要5分鐘運行?
更新:我看了其他可能的重複,such as this one,但我不認爲它們適用。首先,我不是在循環中增加任何內容。在每行添加到db.Workers
之後,我正在對db.SaveChanges();
進行單個調用。這應該是批量插入的最快方式。其次,我已將db.Configuration.AutoDetectChangesEnabled
設置爲false
。現在撥打SaveChanges()
需要00:05:11.2273888(換句話說,大致相同)。我不認爲這真的很重要,因爲每一行都是新的,因此沒有變化來檢測。
我想我正在尋找的是一種發佈包含所有16,000技能的單個UPDATE語句的方法。
您是否嘗試過搜索?關於在Entity Framework中批量插入有很多問題,請參閱例如[在實體框架中插入的最快方式](http://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework) 。 – CodeCaster
可能禁用自動檢測更改:http://stackoverflow.com/questions/5943394/why-is-inserting-entities-in-ef-4-1-so-slow-compared-to-objectcontext/5943699#5943699 – GendoIkari
看起來像http://stackoverflow.com/questions/5940225/fastest-way-of-inserting-in-entity-framework的副本給我。 – JamieSee