与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?