Dispose 后访问的 DataContext

发布于 2024-10-06 05:14:56 字数 921 浏览 6 评论 0原文

我正在使用 ASP.NET 4.0。

我得到以下代码,该代码返回错误“无法访问已处置的对象。 对象名称:“Dispose 后访问的 DataContext。”。“

 public IEnumerable<BatchHeader> GetHeaders()
            {
                using(NSFChecksDataContext context = DataContext)
                {
                    IEnumerable<BatchHeader> headers = (from h in context.BatchHeaders
                                                        select h);                
                    return headers;                            
                }
            }

如果我将其更改为:

public IEnumerable<BatchHeader> GetHeaders()
        {
            using(NSFChecksDataContext context = DataContext)
            {            
                return context.BatchHeaders.ToList();                            
            }
        }

它将正常工作。我正在使用此方法来填充 RadGrid。任何人都可以解释为什么第二种方法可以工作,但第一个方法不行?

谢谢。

I'm using ASP.NET 4.0.

I've got the following code that returns with an error of "Cannot access a disposed object.
Object name: 'DataContext accessed after Dispose.'."

 public IEnumerable<BatchHeader> GetHeaders()
            {
                using(NSFChecksDataContext context = DataContext)
                {
                    IEnumerable<BatchHeader> headers = (from h in context.BatchHeaders
                                                        select h);                
                    return headers;                            
                }
            }

If I change this to:

public IEnumerable<BatchHeader> GetHeaders()
        {
            using(NSFChecksDataContext context = DataContext)
            {            
                return context.BatchHeaders.ToList();                            
            }
        }

It will work fine. I'm using this method to populate a RadGrid. Can anyone explain why the second method will work but not the first?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黑凤梨 2024-10-13 05:14:56

第一个不起作用,因为当该方法返回时,在 using 块中实例化的数据上下文将被释放。但是,返回的 IEnumerable是延迟计算的,并且需要此数据上下文处于活动状态才能枚举其结果。

您可以执行如下操作:

 public IEnumerable<BatchHeader> GetHeaders() {
     using(NSFChecksDataContext context = DataContext) {         
         foreach(var header in context.BatchHeaders) {
             yield return header;
         }
     }
 }

第二个块之所以有效,是因为在处理数据上下文之前查询结果已被枚举并存储在内存中。发生这种情况后,就不再需要数据上下文了。但是,在使用像第二个块这样的代码时要小心;如果 BatchHeaders 表很大,您只需将其全部拉入内存即可。

现在,这是我的答案中最重要的部分:我绝对无法忍受看到实例化要执行的数据上下文的查询。我想知道并控制我的数据上下文何时被使用。

The first doesn't work because when the method returns the data context instantiated in the using block is disposed. However, the IEnumerable<BatchHeader> returned is lazily evaluated and needs this data context to be alive to enumerate its results.

You could do something like this:

 public IEnumerable<BatchHeader> GetHeaders() {
     using(NSFChecksDataContext context = DataContext) {         
         foreach(var header in context.BatchHeaders) {
             yield return header;
         }
     }
 }

The second block works because the query results are enumerated over and stored in memory before the data context is disposed of. After that happens, the data context isn't needed anymore. However, be careful when using code like your second block; if the BatchHeaders table is large you just pulled it all into memory.

Now, and here is the most serious part of my answer: I absolutely can't stand seeing queries that instantiate data contexts to execute. I want to know and control when my data contexts are being used.

烦人精 2024-10-13 05:14:56

我猜测您上下文中的 IEnumerable 正在使用延迟执行,因此除非您强制它使用 ToList 进行枚举,否则它不会这样做,直到您使用这些值,在本例中,该值位于 using 块之外,因此该对象将是处置。

I'm guessing the IEnumerable from your context is using deferred execution, so unless you force it to enumerate using ToList it doesn't do so until you use the values, which in this case is outside of the using block so the object will be disposed.

伴梦长久 2024-10-13 05:14:56
return headers.AsEnumerable(); 

应该可以工作,因为默认情况下,linq 查询返回一个 IQueryable 对象,这意味着在使用 foreach、ToArray、ToList 或 AsEnumerable 枚举之前不会从数据库中获取数据。当 Asp.Net 尝试访问 IQueryable 并使用 foreach 获取数据时,连接已关闭。

return headers.AsEnumerable(); 

should work, because by default, a linq query returns an IQueryable object, which means that the data is not fetched from db until enumerated using foreach, ToArray, ToList or AsEnumerable. When Asp.Net tried to access the IQueryable and fetch the data using foreach, the connection was already closed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文