Служба IQueryable WebAPI: зачем мне вызывать .ToList()?

Я унаследовал этот код от разработчика, который ушел на прошлой неделе. Его код основан на статье:
"Restful WCF / EF POCO / UnitOfWork / Repository / МЭФ".

Этот метод работает (когда я перехожу к http://myapp/myservice/Returns):

[WebGet(UriTemplate = "Returns")]
public IQueryable<ReturnSnapshot> GetReturnSnapshots()
{
    using (UnitOfWork)
    {
        ReturnSnapshotsRepository.EnrolInUnitOfWork(UnitOfWork);
        return ReturnSnapshotsRepository.FindAll().ToList().AsQueryable();
    }
}

но не приведет ли ToList() к извлечению всей таблицы из репозитория? У нас будет более 500 тыс. строк в производстве.

Я подумал, что могу изменить последнюю строку на это:

return ReturnSnapshotsRepository.FindAll();

поскольку FindAll возвращает IQueryable. Однако мое изменение ломает службу, которая теперь вылетает с ошибкой HTTP 12152.

Что я должен делать?


person Merenzo    schedule 14.02.2012    source источник
comment
Что такое ошибка HTTP 12152?   -  person Gabe    schedule 14.02.2012
comment
ERROR_WINHTTP_INVALID_SERVER_RESPONSE 12152 Невозможно проанализировать ответ сервера. -- Начиная с Windows Server 2003 и Windows XP с пакетом обновления 2 (SP2), максимальный объем данных заголовка, которые WinHTTP принимает в ответе HTTP, по умолчанию составляет 64 КБ. Если HTTP-ответ сервера содержит более 64 КБ общих данных заголовка, WinHTTP отклоняет запрос с ошибкой ERROR_WINHTTP_INVALID_SERVER_RESPONSE.   -  person dtb    schedule 14.02.2012
comment
Почему вы избавляетесь от своей единицы работы перед выполнением запроса? Мне это кажется неправильным.   -  person CodesInChaos    schedule 14.02.2012


Ответы (2)


Вы должны иметь возможность вернуть IQueryable<T> из службы REST веб-API WCF. Я подозреваю, что использование блока вызывает вашу проблему, потому что UnitOfWork удаляется, как только вы возвращаетесь из этого метода, но до того, как фактический запрос к базе данных может быть выполнен. Добавление ToList() решает эту проблему, но, как вы указали, делает это, сначала загружая все в память, поэтому это далеко не идеально.

person Maurice    schedule 14.02.2012
comment
Перфекто. Ну, во всяком случае на первый взгляд :) Я избавился от ненужных using и ToList(), и теперь сервис работает как положено. SQLProfiler показывает, что происходит отложенное выполнение, то есть он обслуживает $top=1, а не извлекает всю таблицу. - person Merenzo; 15.02.2012

Я не верю, что это может быть раскрыто через WCF, это может объяснить дальнейшее

Представить IQueryable через службу WCF

person TheRealTy    schedule 14.02.2012