Paginated результаты поиска с LINQ to SQL
Какой лучший шаблон для получения постраничных результатов с LINQ to SQL?
У меня есть следующий сценарий:
Предположим, что я хочу искать таблицу элементов по описанию. Я легко могу сделать:
public IQueryable<Item> FindItemsByDescription(string description)
{
return from item in _dc.Items
where item.Description.Contains(description);
}
Теперь, что было бы лучшим способом для разбиения на страницы этого набора результатов?
- Должен ли я выполнять запрос количества, прежде чем делать это, чтобы узнать размер набора результатов, а затем ограничить этот запрос в соответствии с тем, что я хочу? Я чувствую, что это путь.
- Должен ли я выполнять полный запрос, считать количество из массива и возвращать только разбитое на подмножество подмножество из этого массива? Я чувствую, что это будет огромная трата времени, если набор результатов достаточно велик... Или LINQ to SQL делает какую-то магию здесь?
Существует ли общий шаблон LINQ to SQL для выполнения этой операции?
EDIT: Я должен прояснить одну мелочь. Я знаю методы Take and Skip. Но прежде чем использовать Take и Пропустить, как мне получить итоговое количество результатов, которые запрос будет получать?
Ответы
Ответ 1
Шаблон для пейджинга очень прост. Это связано с использованием методов расширения 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);
}
ОБНОВЛЕНИЕ: Чтобы получить общий счет, просто используйте метод 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 и т.д.
Ответ 2
Вы можете использовать метод расширения Take:
public IQueryable<Item> FindItemsByDescription(string description, int resultAmount)
{
return from item in _dc.Items
where item.Description.Contains(description).Take(resultAmount);
}
Вы можете сделать этот шаг дальше и использовать Skip для последующих "страниц":
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);
}