2010-08-26 10 views
19

Ho un modulo di Windows con due DataGridView (DGV) che contengono più di 25.000 record e 21 colonne ciascuno. Ho caricato con successo ciascuno con i dati dal DB utilizzando un DataAdapter e quindi ho provato semplicemente riempiendo i DGV usando i loop. Ogni metodo ha impiegato circa la stessa quantità di tempo. La prima volta che i dati vengono riempiti nei DGV richiede troppo tempo (7+ ​​minuti), e quindi le volte successive il tempo è molto più ragionevole (~ 30 secondi). Quindi la mia domanda è: qual è il modo migliore per caricare un DGV con una grande quantità di dati che richiederà in media < = 1 minuto? Mi piace molto la funzionalità dei DGV, ma se la spinta arriva a spingere, sono disposto a utilizzare una tecnologia diversa, anche se ciò significa rinunciare ad alcune di queste funzionalità.Il modo migliore per riempire DataGridView con una grande quantità di dati

+4

Conoscete la modalità virtuale? Non caricheresti tutti i dati. Il DGV ti dirà "Ho bisogno dei record 146-203" e tu recuperi solo quelle righe. http://msdn.microsoft.com/en-us/library/15a31akc.aspx – Jonathan

+0

Grazie Jonathan !! Sembra quello di cui ho bisogno. Tuttavia, ho una domanda. Il prossimo passo nell'app è quello di confrontare i due DGV. Avrò ancora accesso all'intero set di dati quando li paragono programmaticamente? – Bkins

risposta

29

ci sono fondamentalmente 3 modi per visualizzare i dati in un DataGridView

  • creare il file manualmente in un ciclo, come si sta facendo: come avete notato, è molto inefficiente se avete un sacco di dati

  • Utilizzare la modalità virtuale di DataGridView, come suggerito da Jonathan nel suo commento: il DGV crea solo il numero di righe che può essere visualizzato e modifica dinamicamente il loro contenuto quando l'utente scorre. È necessario gestire l'evento CellValueNeeded per fornire i dati richiesti al DGV

  • Utilizzare l'associazione dati: questo è di gran lunga il modo più semplice. Basta riempire uno DataTable con i dati dal database utilizzando un DbDataAdapter e si assegna questo DataTable alla proprietà DataSource del DGV. Il DGV può creare automaticamente le colonne (AutoGenerateColumns = true), oppure è possibile crearle manualmente (è necessario impostare DataPropertyName della colonna sul nome del campo che si desidera visualizzare). In modalità database, il DGV funziona come in modalità virtuale, tranne per il fatto che si occupa di recuperare i dati dall'origine dati, in modo da non avere nulla da fare. È molto efficiente anche per un gran numero di righe

6

Penso che sia possibile utilizzare il metodo DataReader invece di DataAdapter. DataReader è un componente oneway molto efficiente, perché legge solo i dati dall'origine e puoi riempire una tabella di dati con il loop.

2

Se si dispone di una quantità enorme di righe, come 10 000 e più,

da evitare perdite prestazioni - fare quanto segue prima l'associazione dati:

dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.EnableResizing; 
//or even better .DisableResizing. 
//Most time consumption enum is DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders 
dataGridView1.RowHeadersVisible = false; // set it to false if not needed 

dopo l'associazione dei dati è possibile attivarlo.

1

Provare a utilizzare un DataTable. Riempilo. Quindi utilizzare un DataView. Assegnarlo a DataSource DataGridView.

//DataView dataView = new DataView(dataTable); 
//this.Grid.DataSource = dataView; 

Otterrete tempi molto piccolo di risposta per file di grandi dimensioni (25000 dischi e 21 colonne in un secondo). Il mio programma modello ha 7 secondi per caricare 100 000 righe * 100 colonne {con contenuti stupide -> numero di riga come stringa}

+0

Ho appena testato questo utilizzando 10 colonne, 6753 righe e ci sono voluti 2: 03.9174603 6735. Il modulo che sto usando è nudo, solo l'altro controllo sul modulo è un pulsante per riempire inizialmente la vista dati. – dmoore1181

+0

Si prega di aggiungere quanto tempo ci è voluto con la modifica ("DataView") e senza di essa. quindi possiamo confrontare quanto è stata la differenza che effettivamente ha dato. – TheBigSot

1

questo risolto il mio problema:

array<DataGridViewRow^> 
    ^theRows = nullptr; 
if (DG->Rows->Count == 0)//First Compilation 
{ 
    int NUMROWS = xxx; 
    theRows = gcnew array<DataGridViewRow^>(NUMROWS); 
    for (int nr = 0; nr < DRH->Count; nr++) 
     theRows[nr] = gcnew DataGridViewRow(); 
//Do not remove the two following 
    DG->Rows->AddRange(theRows); 
    DG->Rows->Clear(); 
} 
else //Update 
{ 

    theRows = gcnew array<DataGridViewRow^>(DG->Rows->Count); 
    DG->Rows->CopyTo(theRows, 0); 
    DG->Rows->Clear(); 

} 
for(int nr=0;nr<theRows->Length;nr++) 
{ 
    theRows [nr]->SetValues("val1", "val2"); 
} 
DG->Rows->AddRange(theRows); 
0

io non sono sicuro che questo è proprio quello che stai chiedendo, ma mi piace creare un sottoinsieme di dati da caricare inizialmente, e quindi includere funzionalità di ricerca. Questo è molto facile da usare con Visual Studio 15 e DataSources/set di dati. In solution explorer, apri il file dataset.xsd. Sarà denominato DataSet.xsd Vai alla tabella dati in questione. Fare clic con il tasto destro e aggiungere una query. Una cosa che faccio comunemente è aggiungere "TOP 1000" alla mia domanda. Quindi, selezionare * da mytable diventa selezionare TOP 1000 * da mytable

Infine, fare doppio clic sul modulo per trovare il metodo _load e modificare il "Fill" per utilizzare la nuova query. Questo potrebbe essere meglio dimostrato con un esempio:

La prima riga di codice che ho commentato è ciò che Vis Stud ha creato per impostazione predefinita. Il secondo è quello che ho aggiunto, che otterrà solo i primi 1000 record.

 private void Form_Customers_Load(object sender, EventArgs e) 
    { 
     // TODO: This line of code loads data into the 'stage2DataSet.customers' table. You can move, or remove it, as needed. 
     /* this.customersTableAdapter.Fill(this.stage2DataSet.customers); */ 
     this.customersTableAdapter.FillBy_Top_1000(this.stage2DataSet.customers); 


    }