2010-08-26 48 views
19

Tengo un formulario de Windows que tiene dos DataGridViews (DGV) que tendrán más de 25,000 registros y 21 columnas cada uno. He cargado con éxito cada uno de los datos de la base de datos usando un DataAdapter y luego traté simplemente de llenar los DGV utilizando for bucles. Cada método tomó aproximadamente la misma cantidad de tiempo. La primera vez que se llenan los datos en los DGV, toma demasiado tiempo (7+ ​​minutos), y luego las veces siguientes el tiempo es mucho más razonable (~ 30 segundos). Entonces mi pregunta es, ¿cuál es la mejor manera de cargar un DGV con una gran cantidad de datos que tomará en promedio < = 1 min? Realmente me gusta la funcionalidad de los DGV, pero si viene el impulso, estoy dispuesto a utilizar una tecnología diferente, incluso si eso significa renunciar a parte de esa funcionalidad.La mejor manera de llenar DataGridView con gran cantidad de datos

+4

¿Conoce el modo virtual? No cargarías todos los datos. La DGV le dirá "Necesito los registros 146-203" y obtendrá solo esas filas. http://msdn.microsoft.com/en-us/library/15a31akc.aspx – Jonathan

+0

Gracias Jonathan !! Eso suena como lo que necesito. Sin embargo, tengo una pregunta. El siguiente paso en la aplicación es comparar los dos DGV. ¿Seguiré teniendo acceso a todo el conjunto de datos al compararlos programáticamente? – Bkins

Respuesta

29

Básicamente hay 3 formas de mostrar datos en un DataGridView

  • crear las filas manualmente en un bucle, como se está haciendo actualmente: como habrán notado, es muy ineficaz si usted tiene una gran cantidad de datos

  • Utilice el modo virtual DataGridView, como sugiere Jonathan en su comentario: el DGV solo crea tantas filas como se pueden mostrar, y cambia dinámicamente sus contenidos cuando el usuario se desplaza. Debe manejar el evento CellValueNeeded para proporcionar los datos requeridos a la DGV

  • Usar databinding: es la forma más fácil. Simplemente complete un DataTable con los datos de la base de datos usando un DbDataAdapter, y asigne este DataTable a la propiedad DataSource del DGV. La DGV puede crear automáticamente las columnas (AutoGenerateColumns = true), o puede crearlas manualmente (debe configurar el DataPropertyName de la columna con el nombre del campo que desea mostrar). En el modo de datos compartidos, el DGV funciona como en modo virtual, excepto que se encarga de buscar los datos del origen de datos, por lo que no tiene nada que hacer. Es muy eficiente incluso para una gran cantidad de filas

6

Creo que puede utilizar el método DataReader en lugar de DataAdapter. DataReader es un componente de una vía muy eficiente, porque solo lee datos de la fuente y puede completar una tabla de datos con bucles.

2

Si usted tiene una gran cantidad de filas, al igual que 10 000 y más,

para evitar la fuga de rendimiento - hacer lo siguiente antes de enlace de datos:

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 

después de la unión es posible que le permitan datos.

1

Intente utilizar una DataTable. Llenarlo. Luego use un DataView. Asignarlo a DataGridView DataSource.

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

Obtendrá tiempos de respuesta muy PEQUEÑOS para archivos grandes (25000 registros y 21 columnas en un segundo).Mi programa plantilla tomó 7 segundos para cargar 100 000 100 * Filas Columnas {con contenidos estúpidos -> número de fila como cadena}

+0

Acabo de probar esto usando 10 columnas, 6753 filas y me tomó 2: 03.9174603 6735. El formulario que estoy usando es escueto, solo otro control en el formulario es un botón para llenar inicialmente la vista de cuadrícula de datos. Por favor, añadir – dmoore1181

+0

¿Cuánto tiempo que tomó con el cambio ("DataView") y sin ella. para que podamos comparar cuánto fue la diferencia que realmente dio. – TheBigSot

1

esto solucionó mi 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

No estoy seguro de que esto es bastante de lo que estás preguntando, pero me gusta crear un subconjunto de datos para cargar inicialmente, y luego incluir la funcionalidad de búsqueda. Esto es muy fácil de hacer usando Visual Studio 15 y DataSources/conjuntos de datos. En el explorador de soluciones, abra su archivo dataset.xsd. Se llamará DataSet.xsd Ir a la tabla de datos en cuestión. Haga clic derecho y agregue una consulta. Una cosa que hago comúnmente es simplemente agregar "TOP 1000" a mi consulta. Por lo tanto, seleccione * de mytable se convierte en TOP 1000 * de mytable

Por último, haga doble clic en su formulario para buscar su método _load y modifique el "Rellenar" para usar su nueva consulta. Esto podría ser mejor demostrado con un ejemplo:

La primera línea de código que le comenté a cabo es lo Vis Stud crea de forma predeterminada. El segundo es el añadí, que obtener sólo las 1000 registros.

 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); 


    } 
Cuestiones relacionadas