LINQ к порядку выполнения сущностей / вопрос времени - PullRequest
0 голосов
/ 29 декабря 2010

У меня есть два длинных запроса, каждый из которых имеет тип "typeViewRequest"

   results1 = ..... (timeout)

   results2=..... (timeout)

Сейчас .....

Случай 1 -----------------------------------------------------------------------------

Если я сделаю

   results1 = ..... .Take(countRecordsToShow/2)
   results2 = ..... .Take(countRecordsToShow/2)

, а затем скажу

   results = results1.Union<typeViewRequest>(results2);

, то это прекрасно работает.Сетка, использующая подкачку, показывает записи countRecordsToShow, здесь нет проблем.

Случай 2 -----------------------------------------------------------------------------

Если я сделаю

   results1 = ..... 
   results2 = .....

, а затем скажу

   results = results1.Union<typeViewRequest>(results2).Take(countRecordsToShow)

, тогда у меня будет тайм-аут.Зачем ?Поскольку мой gridview, очевидно, должен получить количество записей, чтобы установить его подкачку.Мой SelectCountMethod, называемый getPreviousRequestsSelectCount, просто говорит

public int getPreviousRequestsCountFromDB(String name, DateTime dtStart, DateTime dtEnd, ReportedBy_Filter reportedBy, Status_Filter status, ReportType_Filter type, int countRecordsToShow, int userID)
{
return getPreviousRequests(companyNameLike: name, dtStart: dtStart, dtEnd: dtEnd, reportedBy: reportedBy, status: status, type: type, sortExpression: null, userID: userID, countRecordsToShow: countRecordsToShow).Count();
}

Внутри getPreviousRequests, в случае 1, применяется TAKE (как описано в "случае 2"):

results = results1.Union<typeViewRequest>(results2).Take(countRecordsToShow)

, тогда как countRecordsToShow только 20, но это время вышло!Я кеширую это число до тех пор, пока не изменятся критерии фильтрации, да, но все же ...: - ((

Дополнительная проблема: у меня также есть некоторая фильтрация. Эта фильтрация должна происходить в ОБАХ ветвях, например так:

   results1 = .....  Where (something1)

   results2 = ..... .Where (something2)

но если я скажу, как в случае 1,

   results1 = .....  Where (something1).Take(countRecordsToShow/2)

   results2 = ..... .Where (something2).Take(countRecordsToShow/2)

, это отрежет мои отфильтрованные наборы данных, я боюсь - допустим, что countRecordsToShow = 20. Если результаты1 (отфильтрованныечем-то1) было бы, скажем, 15 записей, я бы взял только 10. Если бы результаты2 (отфильтрованные по чему-то2) имели, скажем, 5 записей, я бы взял 5. Тогда у UNION было бы 15 вместо 20 записей.

Обычно я должен сделать это, как в случае 2: ​​

   results1 = .....  Where (something1)

   results2 = ..... .Where (something2)

И затем сказать

results = results1.Union<typeViewRequest>(results2).Take(countRecordsToShow)

Если в отфильтрованных файлах results1.Union (results2) было 25 записей, но countRecordsToShow было 20,тогда так и будет. Я бы просто сказал, что набор данных не завершен, и необходима дополнительная фильтрация.

Но так как мне нужно обрезать набор данных ПЕРЕД СОЮЗОМ, это повлияет на мою фильтрацию ПЛОХО!

Я ожидал, чтоПолученный запрос сначала извлечет каждую ветвь, затем выполнит UNION, затем отфильтрует и затем обрежет прямо в конце.

Что ж, очевидно, если я не обрежу каждую ветку, прежде чем делать что-то еще, я получаюТайм-аут.

Как все это работает?Я ОЧЕНЬ растерялся.Я даже не могу использовать COUNT, чтобы узнать, сколько записей мне следует ожидать, и вести себя как следствие, потому что COUNT перечисляет набор данных, таким образом давая мне тайм-аут.

Какие у меня есть варианты, пожалуйста?(кроме создания sprocs, что мне не разрешено делать).Прямо сейчас единственное «решение», которое я нашел, - это case1 - применить предложение TAKE к каждой из ветвей, ДО СОЮЗА, но, как я уже говорил, это было бы неправильно в отношении фильтрации.

Что я здесь не так делаю?Мне действительно нужно идти с "логически неполноценным" делом1?Пожалуйста, помогите!

Спасибо

Алекс

Примечание:

Я проверил это: Если после выполнения строки

results = results1.Union<typeViewRequest>(results2).Take(20)

Я пытаюсь проверить

results.count()

в ближайшем окне, оно истекло!Разве он не видит, что у него есть предложение .Take (20)?Почему сначала нужно перечислить ВСЕ записи ???Я должен перечислить до предела 20, а затем остановиться.Очевидно, он перечисляет все примерно до 250 000, а затем обрезает набор результатов до 20.

Примечание: я прочитал здесь: Изучение операторов запросов LINQ и плана дифференциального выполнения , что и TAKE, и UNION являютсяdeffered.Итак, почему .... почему TAKE не интегрирован в запрос, а применяется ПОСЛЕ факта?

1 Ответ

0 голосов
/ 30 декабря 2010

Не могу сказать, что понимаю все ваше сообщение, но у меня был недавний опыт, который мог бы применяться здесь.,,и так как у вас ноль постов.,,Я попробую.

У меня было что-то вроде этого:

var results = from ... ;
foreach(results)
{
    do something
}

Отлично работало, но для запуска потребовалось четыре минуты, потому что результаты содержали 4 миллиона записей.Поскольку я новичок в LINQ / EF4, я изменил его на следующее:

var results = from<blah>;
int count = 0;
foreach(results)
{
    if (count++ > 100)
        break;
    do something
}

После этого он завершил работу по истечении оператора foreach после сотой записи и завершил цикл foreach.

После долгих прочтений и экспериментов я пришел к выводу, что запрос будет завершен !!!

Нравится вам это или нет, но запрос будет завершен.

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

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

Тот факт, что результаты вот-вот выйдут за рамки и будут уничтожены, не имел значения.Запрос должен быть завершен.,,Используется или нет.,,запрос должен быть выполнен.

Это было очень разочаровывающее, но поучительное упражнение.

Фрэнк

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