Reputation: 1307
I have several classes based on System.Entity.Data.DbContext. They get used several times a request in disparate ends of the web application - is it expensive to instantiate them?
I was caching a copy of them in HttpContext.Current.Items because it didn't feel right to have several copies of them per request, but I have now found out that it doesn't get automatically disposed from the HttpContext at the end of the request. Before I set out writing the code to dispose it (in Application_EndRequest), I thought I'd readdress the situation as there really is no point caching them if I should just instantiate them where I need them and dispose them there and then.
Questions similar to this have been asked around the internet, but I can't seem to find one that answers my question exactly. Sorry if I'm repeating someone though.
Update
I've found out that disposing of the contexts probably doesn't matter in this blog post, but I'm still interested to hear whether they are expensive to instantiate in the first place. Basically, is there lots of EF magic going on there behind the scenes that I want to avoid doing too often?
Upvotes: 5
Views: 6082
Reputation: 1307
I'm answering my own question for completeness.
This answer provides more information about this issue.
In summary, it isn't that expensive to instantiate the DbContext, so don't worry.
Furthermore, you don't really need to worry about disposing the data contexts either. You might notice ScottGu doesn't in his samples (he usually has the context as a private field on the controller). This answer has some good information from the Linq to SQL team about disposing data contexts, and this blog post also expands on the subject.
Upvotes: 4
Reputation: 15673
Best bet would be to use an IoC container to manage lifecycles here -- they are very, very good at it and this is quite a common scenario. Has the added advantage of making dynamic invocation easy -- meaning requests for your stylesheet won't create a DB context because it is hardcoded in BeginRequest().
Upvotes: 6
Reputation: 364279
Use HttpContext.Items
and dispose your context manually in EndRequest
- you can even create custom HTTP module for that. That is a correct handling. Context disposal will also release references to all tracked entities and allow GC collecting them.
You can use multiple context per request if you really need them but in most scenarios one is enough. If your server processing is one logical operation you should use one context for whole unit of work. It is especially important if you do more changes in transaction because with multiple context your transaction will be promoted to distributed and it has negative performance impact.
Upvotes: 3
Reputation: 4687
We have a web project using a similar pattern to the one you've described (albeit with multiple and independant L2S Contexts instead of EF). Although the context is not disposed at the end of the request, we have found that because the HttpContext.Current becomes unreferenced, the GC collects the context in due course, causing the dispose under the scenes. We confirmed this using a memory analyser. Although the context was persisting a bit longer than it should, it was acceptable for us.
Since noticing the behaviour we have tried a couple alternatives, including disposing the contexts on EndRequest, and forcing a GC Collect on EndRequest (that one wasn't my idea and was quickly receded).
We're now investigating the possibility of implementing a Unit of Work pattern that encompasses our collection of Contexts during a request. There are some great articles about if you google it, but for us, alas, the time it would take to implement outweighs the potential benefit.
On the side, I'm now investigating the complexity of moving to a combined SOA/Unit of Work approach, but again, it's one of those things hindsight slaps you with after having built up an enterprise sized application without the knowledge.
I'm keen to hear other peoples views on the subject.
Upvotes: 0