Как получить данные из очень больших наборов данных с необязательными параметрами? - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть приложение, которое получает данные, запрошенные пользователем.Все параметры, кроме Type, являются необязательными.Если параметр не указан, все элементы извлекаются.Если он указан, извлекаются только элементы, соответствующие этому параметру.Например, здесь я получаю продукты по году выпуска (-1 - это значение по умолчанию, если пользователь не указал его):

var products = context.Products.Where(p => p.type == Type).ToList();
  if (!(Year == -1))
    products = products.Where(p => p.year == Year).ToList();

Это прекрасно работает в течение нескольких лет.Например, если я ищу 2001, я получаю все необходимые записи.Но поскольку products имеет ограниченный размер и извлекает только 1500 записей, более поздние годы просто не извлекаются, а не из списка products, и данные за этот год не отображаются, даже если в БД есть данные.

Как обойти эту проблему?

1 Ответ

0 голосов
/ 26 сентября 2019

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

По сути это означает, что мы можем иметь такой код:

//always adults 
var p = person.Where(x => x.Age > 18);

//we maybe filter on these
if(email != null)
  p = p.Where(x => x.Email == email);
if(socialSN != null)
  p = p.Where(x => x.SSN == socialSN);

var r = p.ToList();  //the query is only actually run now

Несколько вызовов where здесь кумулятивны;они будут концептуально строить предложение where, но не будут выполнять запрос, пока не будет вызван ToList.На этом этапе, если база данных используется, БД видит запрос со всеми его предложениями Where и может использовать индексы и статистику

Если бы мы использовали ToList после каждого Where, то первое Где могло бы попасть вБД и весь его набор данных будут загружены в клиентское приложение, и среда выполнения начнет преобразовывать перечислимое в список (много копирования и выделения памяти).Последующее Где будет фильтровать список в клиентском приложении, перечислять его, но затем снова преобразовывать в список - большая проблема заключается в том, что он выполняется в памяти клиентского приложения в виде некоторого наивного неиндексированного цикла и всех этих миллионов долларов на исследования и разработки.Microsoft потратила много времени на то, чтобы оптимизатор запросов к SQL Server очень быстро извлекал огромные объемы данных:)

Учтите также, что это первое предложение в моем примере - Возраст> 18 может быть огромным;например, миллион людей в возрасте старше 12 лет - для этого предиката верно большое количество данных.Электронная почта или SSN были бы гораздо меньшим набором данных, вероятно, проиндексированы и т. Д. Это надуманный пример, но, надеюсь, хорошо иллюстрирующий точку зрения на производительность;слишком рано, в итоге мы загружаем слишком много данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...