Getting it wrong will cripple your site
The first and foremost reason why you shouldn't use it is that if you set it up wrong the repercussions are critical. Here's my horror story: after ages of head scratching, wondering why the CPUs are continuously nearing 100% and memory leaks are ubiquitous I finally figured out that DataContexts were not being disposed of. Of course this is by design - lovely singleton pattern...Anyway, not only were they not being disposed of they were being instantiated with every access of the data. So we ended up with piles of open connections, which I assume were being terminated randomly by some critical process. This causes huge memory utilisation and huge CPU usage trying to reallocate memory.
Fine so it was implemented incorrectly, but it is practically impossible to see that this is happening during development without shelling out for a decent entity framework profiler (like Entity Profiler - it is very much worth it if you don't trust EF).
Data isn't in sync sometimes...
When we were using the singleton well the data often seemed out of sync with the database. It's as if the ObjectContext knew best and didn't really care what the database had to say. This is not wise when you are working on a web farm since your different servers will have a different view of what the data is in its memory.The way to resolve this is to begin a new connection... In comes the problem of multiplying open and undisposed connections.
Where's the performance gain anyway?
Has anyone any idea of how expensive it is to open a DataContext connection? Answer: "A DataContext is lightweight and is not expensive to create" [citation]. So why is everyone so intent on saving the hassle of creating a DataContext?You are probably saving a few 10s of milliseconds. The word micro optimisation springs to mind - in which case you probably shouldn't be using Entity Framework.
It allows poor coding
Having a DataContext that is never closed allows you to lazy load whenever you want. You may have left your Service and now be in your Controller or worse still, your View. Accessing the database from a View is asking for performance problems as I'm sure you didn't allow that intentionally. It is most likely because you forgot to eager load all the data you need to populate your view.This also makes it hard to keep things nice and streamlined since you don't know where all your queries are coming from.
Conclusion
If you are a guru of Entity Framework and you think a Singleton DataContext is for you then by all means go for it. If you aren't convinced you need it and you're just experimenting you could encounter unexpected and serious problems. Don't use singleton because you think it sounds cool!Also, during fixing up my problems I found the Entity Profiler invaluable. It tracks how many connections have been opened and closed (hopefully they will be equal). It also shows all the actual SQL that is being produced, the results, the query plan and even tips on how to sort your query out. Invaluable!



How did you fix the Singleton Problem?
ReplyDeleteSteve