与ObjectContext相比,为什么在EF 4.1中插入实体很慢?
基本上,我在一个事务中插入35000个对象:
using(var uow = new MyContext()){
for(int i = 1; i < 35000; i++) {
var o = new MyObject()...;
uow.MySet.Add(o);
}
uow.SaveChanges();
}
这需要永远! 如果我使用底层ObjectContex t(通过使用IObjectAdapter ),它仍然很慢,但大约需要20 IObjectAdapter 。 它看起来像DbSet<>正在做一些线性搜索,这需要平方时间...
任何人看到这个问题?
正如Ladislav在评论中指出的那样,您需要禁用自动更改检测以提高性能:
context.Configuration.AutoDetectChangesEnabled = false;
此更改检测在DbContext API中默认启用。
DbContext与ObjectContext API表现如此不同的原因在于,启用自动更改检测时, DbContext API的更多功能将在内部调用DetectChanges不是ObjectContext API的函数。
在这里你可以找到默认调用DetectChanges的函数列表。 他们是:
DbSet上的Add , Attach , Find , Local或Remove成员 GetValidationErrors , Entry ,或SaveChanges上成员DbContext DbChangeTracker上的Entries方法 特别是Add呼叫DetectChanges ,它负责您遇到的糟糕表现。
与此相反, ObjectContext API仅在SaveChanges自动调用DetectChanges ,但不在AddObject和上面提到的其他相应方法中调用DetectChanges 。 这就是为什么ObjectContext的默认性能更快的原因。
为什么他们在DbContext中引入了这种默认的自动更改检测功能? 我不确定,但似乎禁用它并在适当的位置手动调用DetectChanges被认为是高级的,并且可以轻松地将微小的错误引入到您的应用程序中,因此请谨慎使用[it]。
EF 4.3 CodeFirst的经验不多的测试:
使用AutoDetectChanges = true删除1000个对象:23秒
使用AutoDetectChanges = false删除1000个对象:11秒
使用AutoDetectChanges = true插入1000个对象:21秒
使用AutoDetectChanges = false插入1000个对象:13秒
在.netcore 2.0中,这被转移到:
context.ChangeTracker.AutoDetectChangesEnabled = false;
上一篇: Why is inserting entities in EF 4.1 so slow compared to ObjectContext?
