【发布时间】:2017-04-26 20:11:05
【问题描述】:
我在家用计算机上使用 Entity Framework 6 并决定尝试插入相当多的行,大约 430k。
我的第一次尝试看起来像这样,是的,我知道它可以更好,但无论如何它是为了研究:
var watch = System.Diagnostics.Stopwatch.StartNew();
foreach (var event in group)
{
db.Events.Add(event);
db.SaveChanges();
}
var dbCount = db.Events.Count(x => x.ImportInformation.FileName == group.Key);
if (dbCount != group.Count())
{
throw new Exception("Mismatch between rows added for file and current number of rows!");
}
watch.Stop();
Console.WriteLine($"Added {dbCount} events to database in {watch.Elapsed.ToString()}");
晚上开始,下班回家后检查。结果是这样的:
如您所见,在前 4 小时 41 分钟内添加了 64523 个事件,但随后速度变慢了,接下来的 66985 个事件用时 14 小时 51 分钟。我检查了数据库,程序仍在插入事件,但速度极低。然后我决定尝试 DbSet 的“新”AddRange 方法。
我将我的模型从 IDbSet 切换到 DbSet 并将 foreach 循环替换为:
db.Events.AddRange(group);
db.SaveChanges();
我现在可以在大约 30 秒内添加 60k+ 事件。它可能不是SqlBulkCopy 快,但它仍然是一个巨大的改进。为了实现这一目标,幕后发生了什么?我以为我明天要检查 SQL Server Profiler 的查询,但如果能解释一下代码中发生的事情也会很好。
【问题讨论】:
-
这不是因为
Add或AddRange,而是因为Add的版本为每个事件调用db.SaveChanges()。如果你把它移出循环,结果应该是相似的。
标签: c# entity-framework entity-framework-6