Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么我需要ToList()来避免已处理的上下文错误?_C#_Linq_Entity Framework_Asp.net Mvc 5 - Fatal编程技术网

C# 为什么我需要ToList()来避免已处理的上下文错误?

C# 为什么我需要ToList()来避免已处理的上下文错误?,c#,linq,entity-framework,asp.net-mvc-5,C#,Linq,Entity Framework,Asp.net Mvc 5,我正在编写一些代码来使用EntityFrameWork访问数据库。代码是: public IEnumerable<Rows> GetRows(int id) { using (var context = new ApplicationDbContext()) { var repository = new EntityFrameWorkRepository<int, RowEntity>(context); //need a

我正在编写一些代码来使用EntityFrameWork访问数据库。代码是:

public IEnumerable<Rows> GetRows(int id)
{
    using (var context = new ApplicationDbContext())
    {
        var repository = new EntityFrameWorkRepository<int, RowEntity>(context);
        //need a ToList() here to prevent disposed dbcontext errors
        return repository.GetRowsFromDb(id).ToList();
    }
}
public IEnumerable GetRows(int-id)
{
使用(var context=new ApplicationDbContext())
{
var repository=新EntityFrameWorkRepository(上下文);
//此处需要一个ToList()以防止发生dbcontext错误
返回repository.GetRowsFromDb(id.ToList();
}
}
GetRowsFromDb()使用LINQ查询数据库并使用id筛选结果


我最初编写上述方法时没有调用ToList(),但是当我尝试访问返回的IEnumerable中的对象时,我会得到一个关于已被释放的dbcontext的异常。我不明白上面的代码是如何解决问题的,尽管它确实可以工作。我假设ToList()正在深度复制对象,这可能提供了与上下文/数据库所需的分离,但原始对象肯定应该是可用的吗?

如果不调用
。ToList()
将在
using
子句完成后计算可枚举项,因此,数据上下文将在评估查询之前进行处理


IMO,您应该考虑让您的存储库处理这个问题(通过调用<代码> .TistIt()/代码>)否则,这个问题就代表了泄露的实现细节。

没有<代码> toSist](<)>代码>您只返回枚举器而不是实际的对象集合。当您尝试访问集合时,将获取实际对象。但在本例中,您需要的是上下文和存储库,因为您可以从数据库访问它们。但是,由于它已经超出了

using
子句的范围,因此这两个子句都被处理,因此出现了异常。

您需要调用
ToList
ToArray
,或者枚举EF返回的数据的其他方法的原因是,LINQ中的查询执行被延迟:在显式获取数据之前不会处理数据。当您的方法返回获取查询数据的上下文时,查询数据被关闭(您的
using
块会很快处理这种情况),从而导致您看到的异常

这样做是为了使代码不会花费时间处理您不需要的数据。例如,您可以编写通过客户端上的数据开始读取的代码,并在中间停止。如果查询执行没有延迟,那么您可能会花费时间和内存来获取查询的“尾部”,结果却将其丢弃。延迟执行使您处于控制之中:您可以决定在执行过程中要保留哪些数据,或者根据计划对数据执行的操作将整个集合放入内存

我假设ToList()正在深度复制对象

不完全正确-在调用
ToList
之前,您所拥有的只是一个查询。只有通过
ToList
ToArray
等将其枚举或转化为具体集合,才能得到结果

当然原始对象应该是可用的


不-它已被处理,这是您告诉系统对象已完成其工作且不再需要的方式。您仍然有一个未执行的查询这一事实并不能使上下文保持可用状态。

IEnumerables
是惰性的,因此在调用方法中获取任何结果之前,将先释放上下文
ToList
让事情变得急迫。搜索随机相关的“LINQ deffered execution”: