为什么我需要ToList()来避免处置上下文错误?

Cal*_*all 8 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 ToList() here to prevent disposed dbcontext errors
        return repository.GetRowsFromDb(id).ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

GetRowsFromDb()使用LINQ查询数据库并使用id过滤结果.

我最初在没有ToList()调用的情况下编写了上面的方法,但是当我尝试访问返回的IEnumerable中的对象时,我会得到一个关于dbcontext已被处置的异常.我不明白上面的代码如何解决问题,虽然它确实有效.我假设ToList()深度复制对象,这可能提供了与上下文/数据库的必要分离,但是原始对象肯定可以使用吗?

das*_*ght 8

你需要打电话的原因ToList,ToArray或枚举由EF返回的数据的一些其他方法在LINQ查询执行被推迟:数据没有处理,直到你把它明确.当您的方法返回已获取查询数据的上下文时(您的using块会快速处理这种情况),导致您看到的异常.

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


Kir*_*oll 7

如果你不叫.ToList()的枚举进行评估您的using条款完成,因此,数据上下文将评估查询之前布置.

IMO,您应该考虑让您的存储库处理这个(通过调用.ToList()),否则此问题代表泄漏的实现细节.