我想确保我正在处理我的EF dbContext对象。
目前我正在使用静态方法来调用EF crud操作,以便将所有数据层内容保持黑盒子并且不在控制器之外。
下面的示例我有一个方法返回IQueryable并使用Using statment,当查询尝试在已处置的上下文对象上运行时会导致异常。
另一个不使用Using语句并且工作正常但它是否被处理?
我应该只返回IEnumerable而不是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);
}
答案 0 :(得分:4)
问题与使用IQueryable
或IEnumerable
无关。您有异常,因为通过返回IQueryable
或IEnumerable
,您没有执行LINQ。您刚刚打开了与数据库的连接,然后在配置查询后关闭。
要解决此问题,您需要通过调用ToList
,ToArray
,Single[OrDefault]
,First[OrDefault]
等扩展方法来执行LINQ查询。
由于您正在使用Web应用程序,因此最佳做法是在Web请求的整个生命周期中拥有DbContext
的一个实例。我建议你使用DI(依赖注入),它会帮助你很多。您可以尝试Simple Injector这是非常简单的DI。
如果您无法使用DI,请按照以下步骤操作,但请花点时间了解DI请::)
DbContext
的新实例存储到HttpContext.Items
个收藏中。DbContext
检索存储的HttpContext.Items
并使用它。DbContext
。