实体框架批量插入 - 创建大量对象/实体是缓慢的部分?

时间:2016-04-17 19:42:26

标签: c# entity-framework entity-framework-6

在这里和其他地方有很多关于如何使用EF加速批量插入的信息和答案。

但是,我只插入了大约10,000条记录,而且创建实体的速度很慢。

首先,我将外部数据保存到数据表中,然后循环遍历并为每一行创建一个新的entity,在循环中添加子实体(来自其他几个数据表)和一次循环已完成电话db.SaveChanges()

在我的初始分析中,db.SaveChanges()速度很慢,但与首先创建所有对象的循环相比,无论是作为单独的List<entity> entities还是直接与上下文相关。

这是通常的吗?对于批量插入的所有问题,我可以看到,大多数似乎与数据库的最终提交有关。

编辑以添加一些代码请原谅psudo-code

DataTable ref1 = ConvertCSVtoDataTable(csv, firstRowsToDelete: 15); // Return's a Datatable from a CSV

foreach(string file in ListOfFilesToProcess)
{
    DataTable tbl = loadExcelFiles(file);

    foreach(DataRow dr in tbl.Rows)
    {
         Entity newEntity = new Entity();
         Entity.property1 = dr["Property1"].ToString();
         ... // Keep mapping properties to elements in the datatable
         Entity.Child.Add(new ChildEntity() { prop1 = ref1["ChildProp1"].ToString() });
         // Add the newly created entity to the context
         db.Entity.Add(newEntity);
    }
}
// Save the context
db.SaveChanges();

因此,在保存上下文时,会有几千个newEntity个对象及其子navigation个对象。

迭代数据表并创建所有这些对象是最慢的部分!

此外,db.Configuration.AutoDetectChangesEnabled = false;已经设定。

2 个答案:

答案 0 :(得分:1)

“创建所有对象”部分中的缓慢部分是“检测更改”。

您应该始终使用AddRange而不是添加

  • 添加:检测每个对象的更改
  • AddRange:仅检测一次更改(添加所有对象后)

此代码应该在创建对象时修复缓慢的部分:

DataTable ref1 = ConvertCSVtoDataTable(csv, firstRowsToDelete: 15); // Return's a Datatable from a CSV

List<Entity> list = new List<Entity>();

foreach(string file in ListOfFilesToProcess)
{
    DataTable tbl = loadExcelFiles(file);

    foreach(DataRow dr in tbl.Rows)
    {
         Entity newEntity = new Entity();
         Entity.property1 = dr["Property1"].ToString();
         ... // Keep mapping properties to elements in the datatable
         Entity.Child.Add(new ChildEntity() { prop1 = ref1["ChildProp1"].ToString() });

        list.Add(newEntity);
    }
}

// Add all newly created entities to the context
db.Entity.AddRange(list);

// Save the context
db.SaveChanges();

如果在此修复之后,您仍然有一些问题性能(这次来自数据库),您应该尝试使用BulkSaveChanges / Bulk Insert第三方库。

以下是关于这些库的文章:Entity Framework - Bulk Insert Library Reviews & Comparisons

  • 实体框架扩展(推荐,支持所有内容)
  • EntityFramework.BulkInsert
  • EntityFramework.Utilities

免责声明:我是该项目的所有者Entity Framework Extensions

答案 1 :(得分:1)

只需使用批量插入。即使你已经超越了EF糟糕的糟糕表现,你仍然需要与不喜欢单个插页的数据库竞争。