2009-04-27 2 views
21

Каков наилучший шаблон для получения постраничных результатов с помощью LINQ to SQL?Paginated результаты поиска с LINQ to SQL

У меня есть следующий сценарий:

Предположим, я хочу найти пунктов таблицу описанием. Я могу легко:

public IQueryable<Item> FindItemsByDescription(string description) 
{ 
    return from item in _dc.Items 
      where item.Description.Contains(description); 
} 

Теперь, что было бы лучшим способом для разбивки на страницы этого набора результатов?

  1. Должен ли я выполнить счета запрос на прежде чем сделать это, чтобы узнать результат заданного размера, а затем ограничить этот запрос в соответствии с тем, что я хочу? Я чувствую, что это путь.
  2. Должен ли я выполнять полный запрос, считать количество из массива и возвращать только разбитое на подмножество подмножество из этого массива? Я чувствую, что это будет огромная трата времени, если набор результатов достаточно велик ... Или LINQ to SQL здесь немного волшебства?

Есть ли LINQ to SQL общий шаблон для выполнения этой операции?

EDIT: I must уточнить одну мелочь. Я знаю методы Take and Skip. Но, прежде чем использовать Возьмите и Пропустить, как я должен получить общее количество результатов, которые запрос будет получать?

ответ

30

Шаблон для пейджинга очень просто. Она включает в себя использование Skip() и Take() методы расширения следующим образом:

public IQueryable<Item> FindItemsByDescription(string description, int pageIndex, int pageSize) 
{ 
    return from item in _dc.Items 
      where item.Description. 
      Contains(description). 
      Skip((pageIndex - 1) * pageSize). 
      Take(pageSize); 
} 

UPDATE: Для того, чтобы получить общее количество просто использовать метод Count():

int totalCount = from item in _dc.Items 
       where item.Description. 
       Contains(description).Count(); 

int numberOfPages = (int)(totalCount/pageSize); 

В зависимости о том, как вы собираетесь отображать записи, вы можете использовать numberOfPages для отображения навигационной панели с «Страница X of Y» ... Страница 1 из 10 и т. д.

+0

Pablo - я обновил сообщение, чтобы добавить дополнительную информацию о пейджинге. (Salu2) –

+0

Спасибо большое Базилио. Является ли это, производительность разумным, лучший способ сделать это? Знаете ли вы, сколько запросов будет выполняться против SQL-сервера при таком подходе? –

+3

Pablo - код в примере будет выполнять 2 отдельных SQL-запроса. Однако этого не должно быть. Вы можете взять результаты запроса и поместить его в список с помощью ToList(), а затем получить Count().Чтобы вы получили только один вызов в базе данных. –

2

Вы можете использовать метод расширения Take:

public IQueryable<Item> FindItemsByDescription(string description, int resultAmount) 
{ 
    return from item in _dc.Items 
      where item.Description.Contains(description).Take(resultAmount); 
} 

Вы можете сделать еще один шаг вперед и использовать Пропустить для последующих «страниц»:

public IQueryable<Item> FindItemsByDescription(string description, int resultAmount, int page) 
{ 
    return from item in _dc.Items 
      where item.Description.Contains(description).Skip(resultAmount * page).Take(resultAmount); 
} 
+0

Большое спасибо за быстрый ответ. Мне известно о выходе из программы Take and Skip. Однако, если я действительно хочу разбиться на страницы, я должен знать, каково общее количество результатов без разбивки на страницы. Итак, каков наилучший способ получить это * общее число *? –