Продолжает ли выполняться SQL-запрос, сгенерированный из IQueryable, после того, как программа на C # перестает перечислять? - PullRequest
0 голосов
/ 06 ноября 2019

У меня есть база данных с огромным количеством записей. У меня есть критерии фильтрации записей, которые не могут быть переведены в SQL. Рассмотрим следующий сценарий:

IItemRepository repo = new ItemRepository();
IQueryable<Item> items = repo.GetAll();
IEnumerator<Item> itemEnumerator = items.GetEnumerator();
List<BinaryData> binaryDataList = new List<BinaryData>();

while (binaryDataList.Count < 20 && itemEnumerator.MoveNext())
{
    BinaryData binaryData = BinaryData.Extract(itemEnumerator.Current.BinaryData);

    if (IsValidBinaryData(binaryData))
    {
        binaryDataList.Add(binaryData);
    }
}

После выхода из цикла while программа продолжает выполняться на сервере или останавливается? Мне нужно, чтобы это прекратилось, потому что выполнение GetAll() запроса к этой базе данных было бы безумием.

edit: Я слишком упростил сценарий, в данном случае есть несколько фильтров иупорядочение, но в этом нет смысла копировать и вставлять этот сложный код.

1 Ответ

1 голос
/ 06 ноября 2019

Пейджинг - отличный способ справиться со многими результатами.

Ваш комментарий предполагает, что вы знаете о Take и Skip.

Реализация эффективного пейджинга данных содержит полный пример. Вот небольшая часть этого.

public IQueryable<Dinner> FindUpcomingDinners() 

(...)

var upcomingDinners = dinnerRepository.FindUpcomingDinners();

var paginatedDinners = upcomingDinners.Skip((page ?? 0) * pageSize)
                                         .Take(pageSize)
                                         .ToList();

(...)

Entity Framework достаточно умен, чтобы создать оптимизированный запрос SQL, который выполняет эту логику пропуска в SQLбаза данных - а не в веб-сервере. Это означает, что даже если у нас есть миллионы предстоящих Обедов в базе данных, только 10 из них, которые мы хотим, будут извлечены как часть этого запроса (что делает его эффективным и масштабируемым).


Вопрос

Как только программа выходит из цикла while, продолжает ли выполняться запрос на сервере или он останавливается? Мне нужно это остановить, потому что выполнение запроса GetAll () для этой базы данных было бы безумием.

Нет «продолжения» выполнения запроса. Код не выбирает записи одну за другой при перечислении IQueryable. В точке перечисления запрос отправляется в базу данных, все результаты выбираются и затем сохраняются в памяти.

...