使用Entity Framework插入许多行非常慢

时间:2015-11-09 19:00:16

标签: c# .net entity-framework

我正在使用Entity Framework来构建数据库。有两种型号; 工人技能。每个工作人员都有零个或多个技能。我最初从某个地方的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 Profiler,基本上我发现的是成千上万的调用:

INSERT [dbo].[SkillWorkers]([Skill_SkillId], [Worker_WorkerId])
VALUES (@0, @1)

SkillWorkers添加了16,027行,这是一个相当数量的数据,但无论如何都不是很大。有没有办法优化这段代码,所以它不需要5分钟才能运行?

更新:我查看了其他可能的重复项such as this one,但我认为它们不适用。首先,我不是在循环中批量添加任何东西。将每行添加到db.SaveChanges();后,我只对db.Workers进行一次调用。这应该是批量插入的最快方法。其次,我已将db.Configuration.AutoDetectChangesEnabled设置为falseSaveChanges()调用现在需要 00:05:11.2273888 (换句话说,大致相同)。我认为这并不重要,因为每一行都是新的,因此没有更改来检测。

我认为我正在寻找的是一种发布包含所有16,000种技能的单一UPDATE语句的方法。

1 个答案:

答案 0 :(得分:1)

一种简单的方法是使用EntityFramework.BulkInsert扩展名。

然后你可以这样做:

// 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.BulkInsert(workforce);