LINQ to SQL faz isso usando uma função de janela 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;
Isso funciona, mas a necessidade de fabricar o row_number do ORDER BY pode resultar na classificação da sua consulta no lado do servidor e causar problemas de desempenho. Mesmo quando um índice pode satisfazer o requisito ORDER BY, a consulta ainda precisa contar 1000 linhas antes de começar a retornar resultados. Com muita frequência, os desenvolvedores esquecem isso e apenas lançam um controle de paginação sobre uma tabela de 5 milhões de linhas e se perguntam por que a primeira página é retornada muito mais rápido do que a última ...
No entanto, usar ROW_NUMBER () é provavelmente o melhor equilíbrio entre facilidade de uso e bom desempenho, desde que você tenha certeza de evitar a classificação (a condição ORDER BY pode ser satisfeita por um índice).