Доступ К DataContext После Dispose

Я использую ASP.NET 4.0.

у меня есть следующий код, который возвращает с ошибкой "не удается получить доступ к ликвидированному объекту. Имя объекта: 'DataContext доступ после Dispose.'."

 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. Может ли кто-нибудь объяснить, почему второй метод будет работать, но не первый?

спасибо.

3 ответов


первый не работает, потому что, когда метод возвращает контекст данных создается в папке using блок утилизируется. Однако IEnumerable<BatchHeader> returned лениво оценивается и нуждается в этом контексте данных, чтобы быть живым, чтобы перечислить его результаты.

вы могли бы сделать что-то вроде этого:

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

второй блок работает, потому что результаты запроса перечисляются и хранятся в памяти до удаления контекста данных. После этого контекст данных не будет больше не нужна. Однако будьте осторожны при использовании кода, такого как ваш второй блок; если BatchHeaders таблица очень большая, вы просто вытащили все это в памяти.

теперь, и вот самая серьезная часть моего ответа:Я абсолютно не могу видеть запросы, которые создают контексты данных для выполнения. Я хочу знать и контролировать, когда используются мои контексты данных.


Я предполагаю, что IEnumerable из вашего контекста использует отложенное выполнение, поэтому, если вы не заставляете его перечислять с помощью ToList, он не делает этого, пока вы не используете значения, которые в этом случае находятся вне блока using, поэтому объект будет удален.


return headers.AsEnumerable(); 

должен работать, потому что по умолчанию запрос linq возвращает объект IQueryable, что означает, что данные не извлекаются из БД до перечисления с помощью foreach, ToArray, ToList или AsEnumerable. Когда Asp.Net пытался получить доступ к IQueryable и получить данные с помощью foreach, соединение уже было закрыто.