在教程这里之后,我试图返回IQueryable,但是我得到了错误,操作无法完成,因为DbContext已被释放
public class ProductsController : ODataController
{
[EnableQuery]
public IQueryable<Product> Get()
{
return GetRepository<Product>().GetQueryable();
}
}GetRepository()是一个更大的泛型DI和工作模式单元类的一部分,基本上
public Repository(DbContext context)
{
Context = context;
DbSet = Context.Set<T>();
}
public virtual IQueryable<T> GetQueryable()
{
IQueryable<T> query = DbSet;
return query;
}发布于 2016-11-01 13:19:47
当您从控制器返回IQueryable时,您无法控制运行该IQueryable的时间。正在发生的情况是,在Web管道开始运行IQueryable并返回结果之前,您的IQueryable正在被释放。
您使用GetRepository所做的工作称为服务定位器模式。然而,Web有一种执行依赖注入的机制,这将使您对资源的生存期具有更多的确定性控制。
https://www.asp.net/web-api/overview/advanced/dependency-injection
使用这种方法,构造函数注入服务(GetRepository的返回类型),然后覆盖控制器上的Dispose,以便清理注入的构造函数。一旦控制器运行完毕并返回来自IQueryable的结果,Web将在控制器上调用Dispose,因此您的生存期问题将得到解决。
对于许多常用的IOC容器,NuGet上都有包装器,使它们能够自动地使用Web。
发布于 2016-11-01 13:05:02
如果仔细查看所提供的链接中给出的示例,可以看到它们在响应方法之外具有上下文,并且在控制器上调用Dispose方法之前不会对其进行处理。
public class ProductsController : ODataController
{
ProductsContext db = new ProductsContext();
[EnableQuery]
public IQueryable<Product> Get()
{
return db.Products;
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
}最有可能的是,您将在GetRepository()或GetQueryable()方法中释放创建的上下文。例如,通过应用using。
https://stackoverflow.com/questions/40360419
复制相似问题