基本上,我在一个事务中插入35000个对象:
using(var uow = new MyContext()){ for(int i = 1; i < 35000; i++) { var o = new MyObject()...; uow.MySet.Add(o); } uow.SaveChanges(); }
这需要永远!如果我使用基础ObjectContext(通过使用IObjectAdapter),它仍然很慢,但大约需要20秒。似乎DbSet<>正在执行一些线性搜索,这需要花费大量时间…
ObjectContex
IObjectAdapter
DbSet<>
还有其他人看到这个问题吗?
正如Ladislav在评论中已经指出的那样,您需要禁用自动更改检测以提高性能:
context.Configuration.AutoDetectChangesEnabled = false;
默认情况下,DbContextAPI中启用了此更改检测。
DbContext
DbContext行为与ObjectContextAPI 如此不同的原因是,启用自动更改检测后,与API的函数相比,API的内部函数DbContext要调用的更多。DetectChanges``ObjectContext
ObjectContext
DetectChanges``ObjectContext
在这里,您可以找到DetectChanges默认调用的那些函数的列表。他们是:
DetectChanges
Add
Attach
Find
Local
Remove
DbSet
GetValidationErrors
Entry
SaveChanges
Entries
DbChangeTracker
特别是导致您体验不佳的Add呼叫DetectChanges。
与此形成对比的是,ObjectContextAPI DetectChanges仅自动调用,SaveChanges而不会自动调用AddObject上述其他相应方法。这就是为什么 默认 性能ObjectContext更快的原因。
AddObject
他们为什么DbContext在这么多功能中引入了这种默认的自动更改检测功能?我不确定,但是DetectChanges在适当的时候禁用它并手动调用似乎是高级的,并且可以轻松地将细微的错误引入您的应用程序,因此请谨慎使用[it]。