Конкретным новичком себя назвать не могу, раньше уже с С# дело имела, как и с DataGridView (дальше DGV), но раньше до скорости загрузки данных дела не было (данных было мало, да и сами БД по структуре были достаточно простые), а вот сейчас стал вопрос ускорения загрузки данных в DGV. Скажу сразу, что в коде не использую запросы SQL, в качестве БД использую Firebase.
Сейчас использую такую конструкцию:
Формирование столбцов таблицы:
dt.Columns.Add("ID");
dt.Columns.Add("КЗ");
dt.Columns.Add("ДЗ");
dt.Columns.Add("Студент");
dt.Columns.Add("Дисципліна");
dt.Columns.Add("Тип");
dt.Columns.Add("Дата");
UploadTable();
Собственно сама загрузка данных в DGV (вернее, код автоматического обновления таблицы после создания/обновления/удаления оценок):
List<BLL.DTOs.MarkDTO> temp = marksService.GetMarksByInstitute(institute);
dt.Rows.Clear();
foreach (var elem in temp)
{
DataRow row = dt.NewRow();
row["ID"] = elem.ID;
row["КЗ"] = elem.Short_Value;
row["ДЗ"] = elem.Long_Value;
row["Студент"] = studentsService.GetFIOByID(elem.Student_ID);
row["Дисципліна"] =
disciplinesService.GetNameById(elem.Discipline_ID);
row["Тип"] = elem.Type;
row["Дата"] = elem.Date;
dt.Rows.Add(row);
}
DataView dataView = new DataView(dt);
dataGridView1.DataSource = dataView;
При такой конструкции загрузка 20-25 записей занимает около 12-14 секунд, что явно многовато, учитывая, что записей по плану будет явно больше чем 20. Немного изменив код:
dt.Columns.Add("ID");
dt.Columns.Add("КЗ");
dt.Columns.Add("ДЗ");
dt.Columns.Add("Студент");
dt.Columns.Add("Дисципліна");
dt.Columns.Add("Тип");
dt.Columns.Add("Дата");
dataGridView1.DataSource = dt;
UploadTable();
List<BLL.DTOs.MarkDTO> temp = marksService.GetMarksByInstitute(institute);
dt.Rows.Clear();
foreach (var elem in temp)
{
DataRow row = dt.NewRow();
row["ID"] = elem.ID;
row["КЗ"] = elem.Short_Value;
row["ДЗ"] = elem.Long_Value;
row["Студент"] = studentsService.GetFIOByID(elem.Student_ID);
row["Дисципліна"] = disciplinesService.GetNameById(elem.Discipline_ID);
row["Тип"] = elem.Type;
row["Дата"] = elem.Date;
dt.Rows.Add(row);
}
получаю примерно те же результаты (разве что, записи появляются не сразу в таблице, а постепенно по одной, что, конечно, интересно наблюдать, но все равно это долговато).
Понимаю, что, скорее всего, решение простое, но я реально пока не знаю что делать. Очень хочется, что бы результаты прогружались достаточно быстро (в пределах 3 секунд, в идеале).
Иными словами, есть список оценок (второй фрагмент кода, переменная temp), и нужно быстро перенести его в DGV.
Функция UploadTable - это как раз тот второй кусок кода.
Данные сервисы получают данные с одной и той же удаленной БД (я упоминала Firebase).
Я тоже сначала проверила именно сервисы, но их я уже изменила, и они запросы выполняют достаточно быстро.
Основная проблема - именно с отрисовкой самой таблицы. Вариантом присвоения списка свойству DataSource я воспользовалась, и теперь таблица прогружается и обновляется реально быстро (1-2 секунды) даже при большом кол-тве данных, но появилось два нюанса - столбцы переименовались с нормальных названий на названия полей, и значения в строках повторяет в точности значения объектов в списке.
Вопрос с названиями столбцов решился (топорно, правда, но работает) - я просто в коде создаю столбцы.
dataGridView1.Columns.AddRange(
new DataGridViewTextBoxColumn() { Name = "clmID", HeaderText = "ID", DataPropertyName = "ID" },
new DataGridViewTextBoxColumn() { Name = "clmShortValue", HeaderText = "КЗ", DataPropertyName = "Short_Value" },
new DataGridViewTextBoxColumn() { Name = "clmLongValue", HeaderText = "ДЗ", DataPropertyName = "Long_Value" },
new DataGridViewTextBoxColumn() { Name = "clmStudent", HeaderText = "Студент", DataPropertyName = "Student_ID" },
new DataGridViewTextBoxColumn() { Name = "clmDiscipline", HeaderText = "Дисципліна", DataPropertyName = "Discipline_ID" },
new DataGridViewTextBoxColumn() { Name = "clmType", HeaderText = "Тип", DataPropertyName = "Type" },
new DataGridViewTextBoxColumn() { Name = "clmDate", HeaderText = "Дата", DataPropertyName = "Date" },
new DataGridViewTextBoxColumn() { Name = "clmTeacher", HeaderText = "Викладач", DataPropertyName = "Teacher_ID" }
);
Что до основной проблемы (скорость), то да, обращений действительно много (и там циклы, что замедляет работу). Решение вижу в Linq, так что буду рефакторить остальной код приложения.
dataGridView1.DataSource = temp;. Если нужна двусторонняя привязка (two-way binding), то вместоList<T>используемBindingList<T>. – Alexander Petrov Dec 25 '22 at 14:35UploadTable();. Для чего? Что он делает? Не он ли тормозит? – Alexander Petrov Dec 25 '22 at 14:39studentsService.GetFIOByID,disciplinesService.GetNameByIdвыполняются в цикле, много раз. В большинстве бизнес-приложений узким местом является работа с БД. Правильное решение: использовать один sql-запрос с join для получения всех необходимых данных. – Alexander Petrov Dec 25 '22 at 18:41