实体框架性能问题,saveChanges非常慢

use*_*232 26 entity-framework

最近,我正在做一些简单的EF工作.很简单,首先,

List<Book> books = entity.Books.WHERE(c=>c.processed==false)ToList();  
then  
    foreach(var book in books)  
    {  
      //DoSomelogic, update some properties,   
    book.ISBN = "ISBN " + randomNumber();  
    book.processed = true;  
    entity.saveChanges(book)  
    }  
Run Code Online (Sandbox Code Playgroud)

我把entity.saveChanges内部的foreach,因为它是一个大名单,100k左右的记录,如果这个记录是没有问题的处理,则标志该记录集book.processed = true,如果该过程由异常中断,那么接下来的时间,我不不得不再次处理这些好的记录.

一切似乎都没问题.处理数百条记录时速度很快.然后当我们移动到100k记录时,entity.saveChanges非常慢.每条记录约1-3秒.然后我们保留实体模型,但entity.saveChanges用经典替换SqlHelper.ExecuteNonQuery("update_book", sqlparams).它非常快.

谁能告诉我为什么实体框架过程那么慢?如果我仍然想使用entity.saveChanges,那么提高性能的最佳方法是什么?

谢谢

Ste*_*eve 32

在执行插入之前关闭更改跟踪.这将显着改善您的表现(秩序的大小).放在SaveChanges()你的循环之外也会有所帮助,但关闭变更跟踪将会有所帮助.

using (var context = new CustomerContext())
{
    context.Configuration.AutoDetectChangesEnabled = false;

    // A loop to add all your new entities

    context.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此页面.

  • 关闭它会产生什么负面影响? (13认同)
  • 就我而言,我使用了 `context.ChangeTracker.AutoDetectChangesEnabled = false;` (3认同)

Dan*_*hew 8

我也可能会建议您将 SaveChanges() 排除在循环之外,因为它会对数据库进行“n”次更新,因此上下文将有“n”次迭代所需的检查点和验证。

var books = entity.Books.Where(c => c.processed == false).ToList();

books.Foreach(b =>
{
    b.ISBN = "ISBN " + randomNumber();
    b.processed = true;
    //DoSomelogic, update some properties  
});
entity.SaveChanges();
Run Code Online (Sandbox Code Playgroud)


Kyl*_*mes 7

我会把foreChanges(书)放在foreach之外.由于book在实体上作为列表,因此您可以将其放在外部,EF将更好地使用生成的代码.

该列表是实体的属性,EF旨在优化后端数据库上的更新/创建/删除.如果你这样做,我会好奇它是否有帮助.