Disposing the entity data context

Last post 01-07-2009 4:13 PM by ShadowChaser. 4 replies.

Sort Posts:

  • Disposing the entity data context

    01-07-2009, 1:54 AM
    • Member
      64 point Member
    • ShadowChaser
    • Member since 12-31-2008, 5:00 PM
    • Posts 40

    Awhile back I read a blog post stating that you shouldn't dispose of a data context in a controller action, like this:

     using (dataContext)  
     {  
         var table = dataContext.GetTable();  
         var products = from p in table select p;  
         return View("List", p);  
     }  

    The argument was that ObjectDisposedExceptions will occur because the data context will be disposed before the view is ever processed by the controller. The blog poster argued that it wasn't really necessary since the data context managed connections internally.

    I disagree. I worry that:

    • If an exception occurs within the data context, there's no guarantee that the data context will be able to close the collection gracefully. If a number of exceptions occur within a short period of time, on a busy site this could effectively cause it to become unresponsive.
    • There's no "contract" that specifies the connection will always be closed when I assume it will be. The MSDN LINQ to SQL FAQ states that the database connection can remain open with certain connection string settings.

    In any event, I'm using LINQ to Entities, but I believe the same issues apply.

    I ended up putting on my "Classic .NET Hat" and wrote:

    public abstract EntityController : System.Web.Mvc.Controller
    {
        private MyObjectContextClass entities;
    
        protected EntityController()
        {
        }
    
        protected MyObjectContextClass Entities
        {
            get
            {
                if (this.entities == null)
                {
                    this.entities = new MyObjectContextClass();
                }
                return this.entities;
            }
        }
    
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
     
            if (disposing && this.entities != null)
            {
                this.entities.Dispose();
            }
        }
    }

    All of my controllers that use that specific Entity Model inherit from this base class, giving me extremely convenient access to the entities while allowing MVC to safely dispose it. Putting a breakpoint into the Dispose method does seem to indict that the controller instance is created and disposed for each request - is this definitely the case, and is this a good solution to the problem?

     

  • Re: Disposing the entity data context

    01-07-2009, 3:26 AM
    Answer
    • Contributor
      5,129 point Contributor
    • levib
    • Member since 07-23-2007, 11:50 PM
    • Redmond, WA
    • Posts 841
    • AspNetTeam

    You've hit at one of the reasons why we made Controller implement IDisposable - so that you can perform cleanup of any type (including models) that you need to. :)

    Though honestly, I'd just use the using { } pattern as described earlier in your post.  While true that this will cause weirdness since the view tries to enumerate the collection after the context has been disposed, this is easily worked around by calling ToList() or some similar method while the context is still within the using { } block:

    using (dataContext) {
    IList<Product> products = dataContext.Products.ToList();
    return View("List", products);
    }
  • Re: Disposing the entity data context

    01-07-2009, 11:40 AM
    • Member
      64 point Member
    • ShadowChaser
    • Member since 12-31-2008, 5:00 PM
    • Posts 40

    Thanks!

    Are there any internal guaruntees about how Controller.Dispose is called by MVC? Specifically how "quickly" it will be called - I imagine it's disposed immediately after the view gets rendered and sent over the response? (in other words, a controller works much the same way "Page" does in the classic ASP.NET event model)

    I'm still debating whether I should use the traditional "using (context)" approach that feels a bit "safer" to me or leaving it on the controller and having it lazily constructed - it's just way too convenient Party!!!

  • Re: Disposing the entity data context

    01-07-2009, 4:07 PM
    Answer
    • Contributor
      5,129 point Contributor
    • levib
    • Member since 07-23-2007, 11:50 PM
    • Redmond, WA
    • Posts 841
    • AspNetTeam

    It's disposed near the end of MvcHandler.ProcessRequest():

    try {
        controller.Execute(RequestContext);
    }
    finally {
        factory.ReleaseController(controller);
    }

    So essentially, it's the very last thing the MVC framework does before removing itself from the call stack and handing control back to the ASP.NET runtime.  As far as whether to dispose of the model in Controller.Dispose() or to use the using { } syntax, it really is just a matter of preference.  Sorry I don't have much guidance for you on that point. :)

  • Re: Disposing the entity data context

    01-07-2009, 4:13 PM
    • Member
      64 point Member
    • ShadowChaser
    • Member since 12-31-2008, 5:00 PM
    • Posts 40

    Thanks! Cool

Page 1 of 1 (5 items)