Reputation: 13
It seems as if the DbContext in the EntityFramework keeps getting slower the more operations (add, delete, modify, querying) you execute on it. Calling periodically SaveChanges() after a few operations won't fix that problem. The only workaround is to dispose the context and regenerate it.
To convey an idea to you: A process, that makes use of one DbContext needs about 4 hours whereas the code with the workaround needs just about 45 minutes, so it's really significant! Is there a reason or switch I don't know?
Upvotes: 0
Views: 2354
Reputation: 10416
It seems as if the DbContext in the EntityFramework keeps getting slower the more operations (add, delete, modify, querying) you execute on it.
It absolutely does - Your DbContext (and the ObjectContext it's based on) saved every entity that it ever touches, loads, updates, saves.
Quick Excerpt from an MSDN blog post:
The more you use an ObjectContext, generally the bigger it gets. This is because it holds a reference to all the Entities it has ever known about, essentially whatever you have queried, added or attached. So you should reconsider sharing the same ObjectContext indefinitely.
Since you said the process takes about 4 hours, I assume you have thousands of entities that are being modified. Save Changes doesn't dump the object graph, you're just creating more and more for it to track. Everytime you make a change, it's having to traverse the graph so the bigger the graph, the longer it takes.
Is your work-around really bad code? Could there be a way to split your process so that each section creates, and disposes of it's own DbContext rather than sharing one?
Upvotes: 1
Reputation:
Here's a useful link for performance considerations for EF5.
Are you using change tracking proxies? If not you may be able to speed things up. From the link:
When a POCO entity does not have a change tracking proxy, changes are found by comparing the contents of your entities against a copy of a previous saved state. This deep comparison will become a lengthy process when you have many entities in your context, or when your entities have a very large amount of properties, even if none of them changed since the last comparison took place.
Otherwise you can set DbContextConfiguration.AutoDetectChangesEnabled = false
as suggested in the comments and links. You can still explicitly call DetectChanges()
after you have done some intensive DbSet/DbContext method calls that would normally auto call it.
Could you also reduce the number of entities in your context? Perhaps use AsNoTracking() queries if you have some entities that do not need to be tracked by the ObjectStateManager.
Upvotes: 1