繁体   English   中英

在MVC控制器中处置EF DBContext

[英]Disposing EF DBContext in MVC controller

我想确保我正在处置我的EF dbContext对象。

目前,我正在使用静态方法来调用EF crud操作,以将所有数据层内容保留在黑框内并且不包含在控制器中。

下面的示例有一个方法,该方法返回IQueryable并使用Using语句,当查询尝试在已处置的上下文对象上运行时,该语句会导致异常。

另一个不使用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);
}

问题不在于使用IQueryableIEnumerable 您有一个例外,因为通过返回IQueryableIEnumerable ,您没有执行LINQ。 您刚打开与数据库的连接,然后在配置查询后关闭。

为了解决这个问题,您需要通过调用ToListToArraySingle[OrDefault]First[OrDefault]等扩展方法来执行LINQ查询。

因为您使用的是Web应用程序,所以最佳实践是在Web请求的整个生命DbContext中拥有一个DbContext实例。 我建议您使用DI(依赖注入),它将对您有很大帮助。 您可以尝试非常简单的DI的Simple Injector

如果您不能使用DI,请按照以下步骤操作,但请花一些时间来学习DI ::

  1. Web请求到达时,将DbContext的新实例存储到HttpContext.Items集合中。
  2. 在您的方法中,只需从HttpContext.Items检索存储的DbContext并使用它即可。
  3. 当Web请求终止时,只需配置DbContext

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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