简体   繁体   中英

Disposing EF DBContext in MVC controller

I want to make sure I'm disposing my EF dbContext objects.

Currently I'm using static methods to invoke EF crud operations to keep all the data layer stuff black boxed and out of the controllers.

The example below I have one method the returns an IQueryable and uses a Using statment which causes an exception when the query tries to run on a disposed context object.

The other doesn't use the Using statement and works fine but is it getting disposed?

Should I just return IEnumerable instead of IQueryable?

public class MyContext : DbContext
{
    public MyContext() : base("MyConnectionString")
    {
        Database.SetInitializer<EFContext>(null);
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
}


public class Data
{
    // Fails when IQuerable tried to run against a disposed MyContext object
    public static T Get<T>(params string[] joins)
    {
        using (var context = new MyContext())
        {
            return context.Get<T>(joins);
        }
    }

    // Works fine but when is it disposed?
    public static T Get<T>(params string[] joins)
    {
        return new MyContext().Get<T>(joins);
    }
}

public ActionResult GetUser(int id = 0)
{
    var data = Data.Get<User>();
    return View("Users", model);
}

The issue is not about using IQueryable or IEnumerable . You have the exception because by returning IQueryable or IEnumerable , you're not executing the LINQ. You just openned a connection to your Database then close after configuring your query.

To solve this, you need to execute the LINQ query by calling ToList , ToArray , Single[OrDefault] , First[OrDefault] etc... extension methods.

Because you're using Web Application, it is a best practice to have one instance of your DbContext in the whole life of your web request. I recommend you to use DI (Dependency Injection), it will help you a lot. You can try Simple Injector which is very simple DI.

If you're not able to use DI so just follow this steps but take a time to learn about DI please :) :

  1. When a web request arrives, store a new instance of your DbContext into HttpContext.Items collections.
  2. In your methods, just retrieve the stored DbContext from HttpContext.Items and use it.
  3. When the web request is terminating, just dispose the DbContext .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM