2009-07-31 3 views
12

Sto scrivendo un'applicazione destop wpf e desidero utilizzare SQL Server CE come back-end. Sto cercando di trovare un buon modo per fare un efficiente paging dei dati. In SQL Server Express, posso fare qualcosa di simile:Paging dati in SQL Server CE (Edizione compatta)

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  

C'è qualcosa di simile in SQL Server CE? Non sono completamente sicuro di cosa sia e non sia supportato. Voglio solo restituire 10 file alla volta dal database, e non dover recuperare tutti i dati e quindi filtrarli verso il basso per visualizzare all'utente, poiché è molto più lento. Grazie.

+0

Neil, vedere il mio commento sulla mia risposta. –

risposta

2

Onestamente, probabilmente la cosa più rapida da fare è utilizzare un SqlCeDataReader e chiamare .Read() 10 volte. Quindi, quando l'utente passa alla pagina successiva, stai già puntando all'undicesimo risultato e puoi leggerne altri 10. Se è necessario tornare indietro, è possibile memorizzare i risultati in cache o passare a uno SqlCeResultSet che supporta seeking.

Inoltre, SqlCeDataReader/Result è, per esperienza, il modo più veloce in assoluto per interagire con il database sul desktop. Può essere letteralmente 100 volte più veloce rispetto all'utilizzo di DataSet/DataAdapters.

+0

Il SqlCeResultSet recupera tutto il set di risultati dal database in una sola volta (come un DataSet disconnesso) oppure apre semplicemente la connessione al database e legge le righe quando vengono richieste? Se lascia una connessione aperta al database, forse posso usare una combinazione di SqlCeResultSet e il metodo ReadAbsolute per saltare ai record che mi servono, leggerli in un elenco, quindi restituire l'elenco e chiudere la connessione. – Neil

+1

@Neil, ResultSet/DataReader richiedono una connessione persistente. Sono praticamente solo un cursore SQL, a tutti gli effetti. Ciò che è particolarmente bello è che puoi anche aprire l'intera tabella come TableDirect, dargli un indice e cercare su quell'indice ed è * così * veloce. –

5

Attualmente sto lavorando a un'applicazione WPF che utilizza SQL Server CE come meccanismo di persistenza. Abbiamo diverse (40+) tabelle e alcune sono piuttosto grandi (record di 50k, almeno questo è grande per i miei standard).

Il mio consiglio sul paging dei dati direttamente in SQL CE è questo: evitatelo se potete! Ho usato l'approccio descritto da Bob King, e almeno per me è risultato in codice Molto brutto, un vero incubo di manutenzione.

A meno che non sia necessario eseguire il controllo di decine di migliaia di record, credo che l'approccio migliore sia caricarli tutti utilizzando SqlCeDataReader in una raccolta di classi personalizzate e quindi sfogliare la raccolta in memoria. Ho trovato questo approccio più reattivo rispetto alla riesecuzione della query SQL ogni volta, anche con la memorizzazione nella cache. Quello che è successo è che nel mio caso le query erano abbastanza complesse, e le prestazioni di SqlCeDataReader erano abbastanza buone da rendere quasi impercettibile il successo della performance. Non c'è bisogno di sottolineare che, dopo il primo caricamento in batch, ogni cambio di pagina avviene quasi istantaneamente perché tutto viene tenuto in memoria.

L'opinione generale dei miei utenti è che è ok aspettare ancora un po 'prima che i primi risultati appaiano, se questo porterà a paging più veloce in seguito. E usando LINQ, il paging è facile come chiamare i metodi Skip e Take. Ho implementato questa logica all'interno di una classe Pager <T>, rendendola molto ASCIUTTA e piacevole.

1

Ci sono alcuni modi, ma il modo più semplice sarebbe simile al seguente:

Supponendo

  1. Formato pagina = 10
  2. Pagina = 2

Poi

  1. Primo TOP = Pa geSize (10)
  2. Seconda TOP = PageSize * Pagina (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
8

Nel caso che qualcuno raggiunge questa pagina cercando la risposta ... mi sono imbattuto di questo post: Il supporto per Le query di paging in SQL Server CE 4,0

http://beyondrelational.com/blogs/jacob/archive/2010/07/13/support-for-paging-queries-in-sql-server-ce-4-0.aspx

Spero che questo aiuti

+0

Grazie a lailalta, SQL Server CE 4.0 non era disponibile al momento in cui originariamente ho postato questa domanda, ma penso che questo sarebbe sicuramente il modo di affrontare il paging in futuro. – Neil

1

ho fatto impl ement impaginazione personalizzata per datagrid utilizzando SQL CE. Ho implementato il metodo per utilizzare la parte superiore dell'istruzione select e saltare i record usando la sottoquery come discusso nella risposta di cui sopra. Ma funziona bene con una piccola quantità di dati. Man mano che i record crescono in migliaia, la metodologia sopra descritta diventa meno utile e diventa lenta nelle prestazioni.

Ho risolto un problema di prestazioni scadente utilizzando la mia tecnica. Quello che ho fatto è memorizzare ID del primo e dell'ultimo record su ogni pagina in variabili.

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

e

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

ho inizializzare queste variabili dopo griglia viene rilegato per ogni pagina.

Se l'utente clicca pulsante accanto prelevo migliori (Pagsize) record dal database più grande di LastRecord Se l'utente clicca sul pulsante precedente prelevo migliori record (PageSize) dal database meno di FirstRecord. Anche io ordino per Id desc in questo caso. E riordina datatable usando dataview per asc prima del binding a datagrid.

Ha reso il mio cercapersone più efficiente. Anche se ho dovuto fare uno sforzo in più per inserire ed eliminare casi di record. Ma sono stato in grado di gestirlo.