因为我从具有上下文Bar
的数据库导入数据到具有MICSYDBCONTEXT
的数据库。
由于BRIA_REALDBCONTEXT
数据库中有280'000条记录,我发现导入10000条记录需要5个小时,因此我迫切需要对查询进行某种优化。我正在使用Entity Framework 6,作为初级开发人员,我将不胜感激。
MICSYDBCONTEXT
答案 0 :(得分:1)
这个问题很常见,
我们可以将其分为三类:
添加与AddRange效果
每次添加新记录时Add方法都会尝试检测更改,而AddRange只执行一次。每次检测更改可能需要几分钟。
这个问题很容易解决,只需创建两个列表,将实体添加到此列表中,并在末尾使用AddRange和列表。
var DLV_DOC_STEPS = new List<DLV_DOC_STEP>();
var DLV_DOCS = new List<DLV_DOC>();
foreach(...)
{
foreach(...)
{
DLV_DOC_STEPS.Add(DLVSTEP);
}
DLV_DOCS.Add(DOC);
}
context2.DLV_DOC_STEP.AddRange(DLV_DOC_STEPS);
context2.DLV_DOC.AddRange(DLV_DOC);
context2.SaveChanges
另一种解决方案是在开始时禁用AutoDetectChange&amp;&amp;在SaveChanges之前重新启用它。我推荐第一个解决方案,但两者都有效。
ctx.Configuration.AutoDetectChangesEnabled = false;
foreach(var item in Doc)
{
// ...code...
}
ctx.Configuration.AutoDetectChangesEnabled = true;
ctx.SaveChanges();
阅读&amp;数据库往返
应用程序正在执行太多的数据库往返
您多次在以下实体中进行查询:
您执行数以百万计的数据库往返是疯狂的,因此您的应用程序当然非常慢!
解决方案
示例:
var defDoctTypeDict = context.DEFDOCTYPE.AsNoTracking().ToList().ToDictionary(x => x.ID);
foreach(var item in Doc)
{
DEFDOCTYPE micsysserviceName;
defDoctTypeDict.TryGetValue(item.DOCTYPE, out micsysserviceName);
if(micsysserviceName != null)
{
// ...code...
}
// ...code...
}
尝试通过创建列表并使用List.Contains批量加载数据 您可以在此处阅读有类似问题的人:https://stackoverflow.com/a/38355262/5619143
如果您不需要跟踪实体,请使用AsNoTracking
写作&amp;数据库往返
每次保存记录时,都会执行数据库往返。
免责声明:我是该项目的所有者Entity Framework Extensions
此库允许执行:
您可以在批处理结束时调用BulkSaveChanges,也可以创建一个列表以直接插入和使用BulkInsert,以获得更高的性能。
BulkSaveChanges解决方案(比SaveChanges更快)
context2.DLV_DOC_STEP.AddRange(DLV_DOC_STEPS);
context2.DLV_DOC.AddRange(DLV_DOC);
context2.BulkSaveChanges
BulkInsert解决方案(最快速度超过BulkSaveChanges但不保存相关实体)
context2.BulkInsert(DLV_DOC_STEPS);
context2.BulkInsert(DLV_DOC);