.Skip (). Take () в свойствах навигации Entity Framework выполняет SELECT * на моем SQL Server - PullRequest
8 голосов
/ 29 декабря 2011

У меня есть метод в моем сгенерированном частичном классе, например:

var pChildren = this.Children
    .Skip(skipRelated)
    .Take(takeRelated)
    .ToList();

Когда я смотрю на свой SQL Server, я вижу, что сгенерированный код выполняет SELECT *.* FROM Children Этот код взят непосредственно измой класс, я подтвердил, что порядок моего Пропуска / Взятия - ДО моего .ToList.

Если я удаляю .ToList, эта строка быстро (и SQL не отправляется в мою БД), но в тот момент, когда я пытаюсь foreach просмотреть результаты, я получаю тот же SQL, отправленный в мою БД: SELECT *.* FROM Children.

Есть ли что-то особенное, что мне нужно сделать при использовании .Skip и .Take в свойствах навигации моих сущностей?

update

Я попытаюсь получить фактический сгенерированный SQL, в данный момент я не настроен для этого.Я нашел первый, потому что он отображается в списке «недавних дорогих запросов» SSMS.

Выполнение этого:

var pChildren = this.Children
    //.Skip(skipRelated)
    //.Take(takeRelated)
    .ToList();

возвращает ~ 4 000 000 строк и занимает ~ 25 секунд.

Выполнение этого:

var pChildren = this.Children
    //.Skip(skipRelated)
    .Take(takeRelated)
    .ToList();

возвращает ~ 4 000 000 строк и занимает ~ 25 секунд.

Как я уже сказал, я возьму сгенерированный для них SQL-запрос и также создам их.

Ответы [ 2 ]

7 голосов
/ 29 декабря 2011

Проблема заключается в том, что вы выполняете запрос LINQ-to-Object при запросе подобной дочерней коллекции.EF загрузит всю коллекцию и выполнит запрос в памяти.

Если вы используете EF 4, вы можете сделать запрос следующим образом

var pChildren = this.Children.CreateSourceQuery()
                 .OrderBy(/* */).Skip(skipRelated).Take(takeRelated);

В EF 4.1

var pChildren = context.Entry(this)
                   .Collection(e => e.Children)
                   .Query()
                   .OrderBy(/* */).Skip(skipRelated).Take(takeRelated)
                   .Load();
1 голос
/ 29 декабря 2011

Поможет ли вам позвонить Skip с результатом Take? т.е.

table.Take(takeCount+skipCount).Skip(skipCount).ToList()

Также см.

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