为什么我需要 ToList() 来避免已处理的上下文错误? [英] Why do I need a ToList() to avoid disposed context errors?

查看:26
本文介绍了为什么我需要 ToList() 来避免已处理的上下文错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing some code to access a database using EntityFrameWork. The code is:

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();
    }
}

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

GetRowsFromDb() uses LINQ to query the database and filter the results using id.

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

I originally wrote the above method without the ToList() call, but when I tried to access objects in the IEnumerable which was returned, I would get an exception about the dbcontext already being disposed. I don't understand how the above code fixes things, although it does then work. I assume ToList() is deep copying the object and that this perhaps provides the required separation from the context/database, but surely the original object should be usable?

推荐答案

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

The reason you need to call ToList, ToArray, or some other method that enumerates the data returned by EF is that query execution in LINQ is deferred: the data is not processed until you take it explicitly. By the time your method returns the context through which the query data has been obtained is closed (your using block takes care of that happening quickly), causing the exception that you see.

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

This is done so that the code is not spending time processing the data that you do not need. For example, you could write code that starts reading through the data on the client side, and stops in the middle. If query execution were not deferred, you would have spent time and memory obtaining the "tail" of the query only to throw it away. Deferred execution puts you in control: you decide what data you want to keep as you go, or bring the entire collection to memory based on what you plan to do with the data.

这篇关于为什么我需要 ToList() 来避免已处理的上下文错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆