Подтвердить что ты не робот

Пейджинг данных в SQL Server CE (Compact Edition)

Я пишу приложение для удаления wpf и хотел бы использовать SQL Server CE в качестве бэкэнд. Я пытаюсь придумать хороший способ сделать эффективный пейджинг данных. В SQL Server Express я могу сделать что-то вроде этого:

Select ID, FirstName, LastName
From (SELECT  ROW_NUMBER() OVER (ORDER BY ID)
 AS Row, ID, FirstName, LastName
 From TestTable                             
) 
WHERE  Row > 1 AND Row <= 10    

Есть ли что-то сопоставимое в SQL Server CE? Я не совсем уверен, что есть и не поддерживается. Я хочу только возвращать 10 строк за раз из базы данных и не возвращать все данные, а затем фильтровать их для отображения пользователю, так как это намного медленнее. Спасибо.

4b9b3361

Ответ 1

Честно говоря, возможно, самое быстрое, что нужно сделать, это использовать SqlCeDataReader и вызвать .Read() 10 раз. Затем, когда пользователь переходит к следующей странице, вы уже указываете на 11-й результат и можете читать еще 10. Если вам нужно вернуться назад, вы можете либо кэшировать свои результаты, либо переключиться на SqlCeResultSet, который поддерживает поиск.

Кроме того, SqlCeDataReader/Result - это, по опыту, самый быстрый способ взаимодействия с базой данных на рабочем столе. Это может быть буквально в 100 раз быстрее, чем использование DataSets/DataAdapters.

Ответ 3

В настоящее время я работаю над WPF-приложением, которое использует SQL Server CE как механизм сохранения. У нас есть несколько (40+) таблиц, и некоторые из них довольно большие (50 тыс. Записей, по крайней мере, для моих стандартов).

Мой совет по обработке данных непосредственно в SQL CE: избегайте этого, если вы можете! Я использовал подход, описанный Бобом Кингом, и, по крайней мере, для меня это привело к очень уродливому коду, кошмару реального обслуживания.

Если вам не нужно будет печатать более десятков тысяч записей, я считаю, что лучший способ - загрузить их все, используя SqlCeDataReader в коллекцию пользовательских классов, а затем страницу по коллекции в памяти. Я нашел этот подход более отзывчивым, чем повторное выполнение SQL-запроса каждый раз, даже при кешировании. Случилось так, что в моем случае запросы были довольно сложными, и производительность SqlCeDataReader была достаточно хороша, так что удар производительности был почти незаметен. Не нужно указывать, что после первой пакетной загрузки каждое изменение страницы происходит почти мгновенно, потому что все хранится в памяти.

Общее мнение моих пользователей заключалось в том, что дождаться, пока первые результаты появятся, будет немного дольше, если это приведет к более быстрому поисковому вызову. И используя LINQ, поисковый вызов так же прост, как вызов методов Skip и Take. Я реализовал эту логику внутри Pager <T> класс, делая его очень сухим и приятным.

Ответ 4

Существует несколько способов, но наиболее упрощенным способом было бы следующее:

Предполагая

  • Размер страницы = 10
  • Страница = 2

Тогда

  • Первый TOP = PageSize (10)
  • Второй TOP = PageSize * Page (20)

SELECT
 [Page].[ID],
 [Page].[FirstName],
 [Page].[LastName]
FROM
(
SELECT TOP (10)
 [FirstRows].[ID],
 [FirstRows].[FirstName],
 [FirstRows].[LastName]
FROM
 (
 SELECT TOP (20)
  [TestTable].[ID],
  [TestTable].[FirstName],
  [TestTable].[LastName]
 FROM
  [TestTable]
 ORDER BY
  [TestTable].[ID] ASC
 ) AS [FirstRows]
ORDER BY 
 [FirstRows].[ID] DESC
) AS [Page]
ORDER BY
  [Page].[ID] ASC

Ответ 5

Я реализовал пользовательский пейджинг для datagrid с использованием SQL CE. Я реализовал метод использования команды top в select и пропущенных записей с использованием подзапроса, как описано в приведенном выше ответе. Но он работает хорошо с небольшим количеством данных. Поскольку показатели растут в тысячах, вышеуказанная методология становится менее полезной и замедляется в производительности.

Я решил проблему с низкой производительностью, используя мою собственную технику. Что я сделал - я храню идентификатор первой и последней записи на каждой странице в переменных.

dim firstRecord=dt.rows(0)("id")

и

dim lastRecord=dt.Rows(dt.rows.count-1)("id")

Я инициализирую эти переменные после привязки сетки для каждой страницы.

Если пользователь нажмет следующую кнопку, я заберу записи верхнего уровня (Pagsize) из базы данных, большей, чем lastRecord  Если пользователь нажимает на предыдущую кнопку, я выбираю записи верхнего уровня (PageSize) из базы данных меньше, чем firstRecord. Также я заказываю Id в этом случае. И измените порядок данных, используя dataview до asc, перед привязкой к datagrid.

Это сделало мой пейджинг наиболее эффективным. Хотя мне пришлось приложить дополнительные усилия для вставки и удаления записей. Но я смог справиться с этим.