Как написать LINQ's. Skip (1000).Взять(100) в чистом SQL?
что такое SQL эквивалент .Skip()
метод в LINQ?
например: я хотел бы выбрать строки 1000-1100 из конкретной таблицы базы данных.
это возможно только с SQL? Или мне нужно выбрать всю таблицу, а затем найти строки в памяти? В идеале я хотел бы избежать этого, если это возможно, так как таблица может быть довольно большой.
6 ответов:
в SQL Server 2005 и выше можно использовать функции row_number. например.
USE AdventureWorks; GO WITH OrderedOrders AS ( SELECT SalesOrderID, OrderDate, ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber' FROM Sales.SalesOrderHeader ) SELECT * FROM OrderedOrders WHERE RowNumber BETWEEN 51 AND 60; --BETWEEN is inclusive
SQL Server 2012 и выше добавили этот синтаксис:
SELECT * FROM Sales.SalesOrderHeader ORDER BY OrderDate OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
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 (), вероятно, является лучшим балансом между простотой использования и хорошей производительностью, если вы убедитесь, что вы избегаете сортировки (порядок по условию может быть удовлетворен индексом).
этого:
выполнить .Пропустить(1000).Возьмите(100) на LINQ to SQL datacontext и посмотрите на вывод SQL. Он будет генерировать SQL-оператор для вас, который делает то, что вы описываете.
Это будет не так элегантно, но он получает работу.