在实体框架中插入的最快方式
我正在寻找插入Entity Framework的最快方式。
我问这是因为你有一个活跃的TransactionScope的场景,插入是巨大的(4000+)。 它可能会持续超过10分钟(事务的默认超时),并且这将导致不完整的事务。
要对你的问题发表评论:
“... SavingChanges( 对于每个记录 )...”
这是你能做的最糟糕的事! 为每个记录调用SaveChanges()
会极大地降低批量插入的速度。 我会做几个简单的测试,这很可能会提高性能:
SaveChanges()
一次。 SaveChanges()
。 SaveChanges()
并处理上下文并创建一个新的上下文。 对于批量插入,我正在尝试使用如下模式:
using (TransactionScope scope = new TransactionScope())
{
MyDbContext context = null;
try
{
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
int count = 0;
foreach (var entityToInsert in someCollectionOfEntitiesToInsert)
{
++count;
context = AddToContext(context, entityToInsert, count, 100, true);
}
context.SaveChanges();
}
finally
{
if (context != null)
context.Dispose();
}
scope.Complete();
}
private MyDbContext AddToContext(MyDbContext context,
Entity entity, int count, int commitCount, bool recreateContext)
{
context.Set<Entity>().Add(entity);
if (count % commitCount == 0)
{
context.SaveChanges();
if (recreateContext)
{
context.Dispose();
context = new MyDbContext();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
我有一个测试程序,向数据库中插入560.000个实体(9个标量属性,无导航属性)。 有了这个代码,它在不到3分钟内就可以工作。
对于性能,重要的是在“许多”记录(“100”或1000左右的“许多” SaveChanges()
之后调用SaveChanges()
)。 它还提高了在SaveChanges之后处理上下文的性能并创建一个新的上下文。 这将清除所有实体的上下文, SaveChanges
不会这样做,实体仍以Unchanged
状态附加到上下文。 在上下文中,连接实体的规模在不断增大,逐步减慢插入。 所以,在一段时间后清除它是有帮助的。
以下是我的560.000个实体的一些测量值:
上面第一个测试中的行为是性能非常非线性,并且随着时间的推移极端降低。 (“许多小时”是一个估计,我从未完成这个测试,20分钟后我停在了50.000个实体。)在所有其他测试中,这种非线性行为并不那么重要。
这种组合提高了速度。
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.ValidateOnSaveEnabled = false;
最快的方法是使用我开发的批量插入扩展。
它使用SqlBulkCopy和自定义数据读取器来获得最佳性能。 因此它比使用常规插入或AddRange快20多倍
用法非常简单
context.BulkInsert(hugeAmountOfEntities);
链接地址: http://www.djcxy.com/p/5733.html
上一篇: Fastest Way of Inserting in Entity Framework
下一篇: How can I get Id of inserted entity in Entity framework?