在这里和其他地方有很多关于如何使用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;
已经设定。
答案 0 :(得分:1)
“创建所有对象”部分中的缓慢部分是“检测更改”。
您应该始终使用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。
免责声明:我是该项目的所有者Entity Framework Extensions
答案 1 :(得分:1)
只需使用批量插入。即使你已经超越了EF糟糕的糟糕表现,你仍然需要与不喜欢单个插页的数据库竞争。