Reputation: 1941
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);
}
Upvotes: 0
Views: 960
Reputation: 23230
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 :) :
DbContext
into HttpContext.Items
collections.DbContext
from HttpContext.Items
and use it.DbContext
.Upvotes: 4