LINQ to SQL делает это с помощью оконной функции ROW_NUMBER:
SELECT a,b,c FROM
(SELECT a,b,c, ROW_NUMBER() OVER (ORDER BY ...) as row_number
FROM Table) t0
WHERE to.row_number BETWEEN 1000 and 1100;
Это работает, но необходимость создания row_number из ORDER BY может привести к тому, что ваш запрос будет отсортирован на стороне сервера и вызовет проблемы с производительностью. Даже если индекс может удовлетворить требование ORDER BY, запрос все равно должен подсчитать 1000 строк, прежде чем он начнет возвращать результаты. Слишком часто разработчики забывают об этом и просто вводят элемент управления разбиением на страницы для таблицы в 5 миллионов строк и задаются вопросом, почему первая страница возвращается намного быстрее, чем последняя ...
Тем не менее использование ROW_NUMBER (), вероятно, является лучшим балансом между простотой использования и хорошей производительностью, при условии, что вы избегаете сортировки (условие ORDER BY может быть выполнено с помощью индекса).