У меня есть форма окна, в которой есть два DataGridViews (DGV), которые будут содержать 25 000 + записей и 21 столбца каждый. Я успешно загрузил каждый из данных из БД с помощью DataAdapter, а затем попробовал просто заполнить DGV, используя для циклов. Каждый метод занимал примерно одинаковое количество времени. В первый раз, когда данные заполняются в DGV, это занимает слишком много времени (7+ минут), а затем в последующие времена время намного разумнее (~ 30 секунд). Поэтому мой вопрос: какой лучший способ загрузить DGV с большим объемом данных, который будет принимать в среднем <= 1 мин? Мне очень нравится функциональность DGV, но если толчок приходит в себя, я готов использовать другую технологию, даже если это означает отказ от некоторых из этих функций.
Лучший способ заполнить DataGridView большим количеством данных
Ответ 1
Существует 3 способа отображения данных в DataGridView
-
Создайте строки вручную в цикле, как вы сейчас делаете: как вы заметили, это очень неэффективно, если у вас много данных.
-
Используйте виртуальный режим
DataGridView
, как предложил Джонатан в своем комментарии: DGV создает только столько строк, сколько может отображаться, и динамически изменяет их содержимое при прокрутке пользователя. Вам нужно обработать событиеCellValueNeeded
, чтобы предоставить необходимые данные в DGV -
Используйте привязку данных: это самый простой способ. Вы просто заполняете
DataTable
данными из базы данных с помощьюDbDataAdapter
, и вы назначаете этотDataTable
свойству DGVDataSource
. DGV может автоматически создавать столбцы (AutoGenerateColumns = true
), или вы можете создать их вручную (вы должны установитьDataPropertyName
в столбце имя поля, которое вы хотите отобразить). В режиме привязки данных DGV работает как в виртуальном режиме, за исключением того, что он заботится о получении данных из источника данных, поэтому вам нечего делать. Это очень эффективно даже для большого количества строк
Ответ 2
Я думаю, вы можете использовать метод DataReader вместо DataAdapter. DataReader - очень эффективный компонент oneway, поскольку он только считывает данные из источника, и вы можете заполнить таблицу данных циклом.
Ответ 3
Если у вас огромное количество строк, например 10 000 и более,
чтобы избежать утечки производительности - перед привязкой данных выполните следующие действия:
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
после привязки данных вы можете включить его.
Ответ 4
Попробуйте использовать DataTable. Заполните. Затем используйте DataView. Назначьте его DataSourceView DataSource.
//DataView dataView = new DataView(dataTable);
//this.Grid.DataSource = dataView;
Вы получите очень малое время отклика для больших файлов (25000 записей и 21 столбца в секунду). Моя программа шаблонов заняла 7 секунд, чтобы загрузить 100 000 строк * 100 столбцов {с глупым содержимым → номер строки как строка}
Ответ 5
это решило мою проблему:
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);
Ответ 6
Я не уверен, что это совсем то, о чем вы просите, но мне нравится создавать подмножество данных для интуитивной загрузки, а затем включать функции поиска. Это очень легко сделать с помощью visual studio 15 и DataSources/data sets. В проводнике решений откройте файл dataset.xsd. Он будет называться DataSet.xsd Перейдите в таблицу данных, о которой идет речь. Щелкните правой кнопкой мыши и добавьте запрос. Одна вещь, которую я обычно делаю, это просто добавить "TOP 1000" в мой запрос. Итак, выберите * from mytable, выберите TOP 1000 * из mytable
Наконец, дважды щелкните по форме, чтобы найти свой метод _load, и измените "Заполнить", чтобы использовать свой новый запрос. Это лучше всего продемонстрировать на примере:
Первая строка кода, которую я закомментировал, - это то, что по умолчанию создало Vis Stud. Второй - тот, который я добавил, который получит только 1000 лучших записей.
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);
}