Как иметь дело с большими наборами результатов с Linq к Объектам?

У меня есть довольно сложный linq к запросу объектов, который я отображаю на веб-сайте. Это использует подкачку страниц так я никогда не выпадающий больше чем 50 записей за один раз для дисплея.

Но я также хочу дать пользователю опцию экспортировать полные результаты в Excel или некоторый другой формат файла.

Мое беспокойство - то, что мог потенциально быть большой # записей все загружаемые в память когда-то, чтобы сделать это.

Существует ли способ обработать linq набор результатов, 1 запись за один раз как Вы могла w/datareader, таким образом, только 1 учет действительно ведут в памяти за один раз?

Я видел предположения, которые, если Вы перечисляете по linq, запрашивают w/цикл foreach, что записи не будут все считаны в память сразу и не были бы overwelm сервер.

У кого-либо есть ссылка на что-то, что я мог считать для проверки этого?

Я ценил бы любую справку.

Спасибо

6
задан user169867 16 June 2010 в 19:48
поделиться

2 ответа

устанавливает для ObjectContext значение MergeOption.NoTracking (поскольку это операция только для чтения). Если вы используете тот же ObjectContext для сохранения других данных, Отсоедините объект от контекста.

как отсоединить

foreach( IQueryable)
{
  //do something 
  objectContext.Detach(object);
}

Edit : Если вы используете опцию NoTracking , нет необходимости отсоединять

Edit2 : Я написал Matt Warren об этом сценарии. И я размещаю здесь соответствующую частную переписку с его одобрения

. Результаты SQL-сервера могут не совпадать. даже все производиться сервером пока что. Запрос начался на сервер и первая партия результатов передаются клиенту, но нет производится больше (или они кэшируются на сервере), пока клиент просит продолжить их чтение. Это то, что называется пожарным шлангом. режим курсора, или иногда называемый как потоковое. Сервер отправляет их как можно быстрее, а клиент читает их так быстро, как только может (ваш код), но есть данные протокол передачи под этим требует подтверждения от клиент, чтобы продолжить отправку дополнительных данных.

Поскольку IQueryable наследуется от IEnumerable , я считаю, что основной запрос, отправленный на сервер, будет таким же. Однако, когда мы выполняем IEnumerable.ToList () , средство чтения данных, которое используется базовым соединением, начинает заполнять объект, объекты загружаются в домен приложения и могут исчерпать память эти объекты пока нельзя утилизировать.

Когда вы используете foreach и IEunmerable , средство чтения данных считывает набор результатов SQL по одному, объекты создаются и затем удаляются. Базовое соединение может получать данные частями и может не отправлять ответ на SQL Server, пока не будут прочитаны все фрагменты. Следовательно, вы не столкнетесь с исключением «нехватки памяти»

Edit3 :

Когда ваш запрос выполняется, вы фактически можете открыть «Монитор активности» SQL Server и увидеть запрос, состояние задачи как SUSPENDED и Тип ожидания как Async_network_IO - что фактически означает, что результат находится в сетевом буфере SQL Server. Вы можете прочитать об этом здесь и здесь

5
ответ дан 17 December 2019 в 00:03
поделиться

Посмотрите на возвращаемое значение запроса LINQ. Это должно быть IEnumerable <> , которое загружает только один объект за раз. Если вы затем используете что-то вроде .ToList () , все они будут загружены в память. Просто убедитесь, что ваш код не поддерживает список и не использует более одного экземпляра за раз, и все будет в порядке.

Изменить: Чтобы добавить к тому, что люди сказали о foreach ... Если вы сделаете что-то вроде:

var query = from o in Objects
            where o.Name = "abc"
            select o;

foreach (Object o in query)
{
   // Do something with o
}

В части запроса используется отложенное выполнение ( см. Примеры ), поэтому объекты пока нет в памяти. Foreach выполняет итерацию по результатам, но за раз получает только один объект. запрос использует IEnumerator , который имеет Reset () и MoveNext () . Foreach вызывает MoveNext () каждый раунд, пока не будет больше результатов.

2
ответ дан 17 December 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: