Доступ к DataContext после удаления - PullRequest
14 голосов
/ 01 декабря 2010

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

У меня есть следующий код, который возвращается с ошибкой «Невозможно получить доступ к удаленному объекту. Имя объекта:« 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.Может кто-нибудь объяснить, почему второй метод будет работать, но не первый?

Спасибо.

Ответы [ 3 ]

16 голосов
/ 01 декабря 2010

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

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

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

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

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

1 голос
/ 01 декабря 2010

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

0 голосов
/ 01 декабря 2010
return headers.AsEnumerable(); 

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

...