Существует ли linq, эквивалентный необработанному sql для подкачки

#c# #entity-framework

#c# #entity-framework

Вопрос:

Я думаю, что следующее эффективно работает независимо от того, есть ли 10 записей или 10 миллионов записей. Существует ли linq-эквивалент, который работает подобным образом?

     class Program
    {
        static void Main(string[] args)
        {
            using (var ctx = new pubsEntities())
            {
                //this will throw an exception
                var studentName = ctx.Database.SqlQuery<employee>(@"
;with CTE AS
(
SELECT *, ROW_NUMBER() over(order by emp_id) AS RowNumber
FROM employee
)
SELECT * FROM CTE
WHERE RowNumber > 2 AND RowNumber <= (2   4)
                ").ToList();
            }
        }
    }
  

Ответ №1:

Вы можете использовать IQueryable<T>.Skip(x).Take(x) для имитации подкачки.

Это довольно просто. Если мы смотрим на ваш код, вы бы хотели что-то вроде этого:

 var pageSize = 100;
var startPage = 2;
var skipAmount = pageSize * startPage;
ctx.Database.Employee.Skip(skipAmount).Take(pageSize);
  

Комментарии:

1. но разве это не замедляется, если имеется 10 миллионов записей?

2. @Rod нет, если поставщик linq переводит его правильно

3. в моем случае используется ключевое слово offset в SQL. Итак, если бы я хотел перейти на последнюю страницу из 10 миллионов записей, смещение было бы равно 9 миллионам. Это не было бы медленным смещением или это имеет значение?

4. @Rod Я на самом деле не знаю с ходу. Я использовал его до 1 миллиона записей без проблем. В рамках Entity Framework (который, как я предполагал, используется здесь) он будет генерировать оптимизированный код в соответствии с правилами EF, после чего оптимизатор SQL получит доступ к нему. Я загляну сюда и посмотрю, смогу ли я сказать, какой запрос в конечном итоге будет выполняться к серверу.