我正在使用实体框架来构建数据库。有两种模式; 工作人员 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