установите ObjectContext
на MergeOption.NoTracking
(так как это операция только для чтения).Если вы используете тот же ObjectContext
для сохранения других данных, Отсоедините объект от контекста.
как отсоединить
foreach( IQueryable)
{
//do something
objectContext.Detach(object);
}
Редактировать : если вы используете опцию NoTracking
, нет необходимости отсоединять
Edit2 : я писал Мэтту Уоррену об этом сценарии.И я публикую здесь соответствующие частные переписки с его одобрением
Результаты, полученные с сервера SQL, могут даже не быть получены сервером.Запрос запущен на сервере, и первая партия результатов передается клиенту, но больше не генерируется (или они не кэшируются на сервере), пока клиент не запросит продолжить их чтение.Это то, что называется режимом «пожарный курсор» или иногда называется потоковой передачей.Сервер отправляет их так быстро, как может, и клиент читает их так быстро, как может (ваш код), но под ним есть протокол передачи данных, который требует подтверждения от клиента для продолжения отправки большего количества данных.
Поскольку IQueryable
наследуется от IEnumerable
, я считаю, что основной запрос, отправляемый на сервер, будет таким же.Однако, когда мы делаем IEnumerable.ToList()
, считыватель данных, который используется базовым соединением, начнет заполнять объект, объекты загружаются в домен приложения и могут исчерпать память, эти объекты еще не могут быть удалены.
Когда вы используете foreach
и IEunmerable
, считыватель данных читает набор результатов SQL по одному, объекты создаются и затем удаляются.Базовое соединение может получать данные в чанках и может не отправлять ответ обратно SQL Server, пока не будут прочитаны все чанки.Следовательно, вы не встретите исключение «нехватка памяти»
Edit3 :
Когда ваш запрос выполняется, вы фактически можете открыть SQL Server «Activity Monitor» исм. запрос, состояние задачи как SUSPENDED и тип ожидания как Async_network_IO
, который фактически указывает, что результат находится в сетевом буфере SQL Server.Вы можете прочитать больше об этом здесь и здесь