Генерация отчетов RDLC занимает так много времени при отображении больших данных
Я работаю с отчетом rdlc над приложением C# windows, извлекая большой набор данных (скажем, 10 000 записей) из базы данных Sqlite, для создания и визуализации отчета требуется более трех минут, я думаю, что это слишком много времени, я попытался сделать небольшую оптимизацию, индексируя все поля в моем предложении where, но никаких улучшений, я не могу сделать хранимую процедуру, так как Sqlite не поддерживает ее.
Что я уже пробовал:
private DataSet GetData() { string select = "SELECT DISTINCT OrganisationId AS OrgId,OrganisationName AS OrgName,TaxIdNumber AS TIN,StaffId,StaffName,Department AS Dept,Position,Month,Year,SUM(NoOfMonthsWorked) AS NMnth," + "SUM(BasicSalary) AS BasicSalary,SUM(TransAllowance) AS Transp,SUM(UtilityAllowance) AS Utility,SUM(HousingAllowance) AS Housing,SUM(LeaveAllowance) AS Leave,SUM(ThirteenthMonthAllowance) AS ThirteenMnth," + "SUM(OvertimeAllowance) AS Overtime,SUM(EntertainmentAllowance) AS EnterMnt,SUM(DomesticAllowance) As Domestic,SUM(EducationAllowance) AS Education,SUM(PersonalAllowance) AS Personal,SUM(OtherAllowances) AS Others," + "SUM(HealthFund) AS NHIS,SUM(HousingFund) AS NHF,SUM(LifeAssurance) AS LA,SUM(Gratuities) AS Gratuities,SUM(Pension) AS Pension,SUM(OtherStatutoryDeductions) AS OtherDeducts," + "SUM(ConsolidatedRelief) AS CRA,SUM(TotalRelief) AS TotalRelief,SUM(TaxableIncome) AS TaxableIncome,SUM(TaxExempts) As TTaxExempt,SUM(GrossIncome) AS GrossIncome,SUM(MonthlyTaxDue) AS TaxPayable " + "FROM IncomeTax WHERE(OrganisationId = @OrganisationId AND Year = @Year) GROUP BY StaffId"; using (SQLiteConnection con = new SQLiteConnection(connstring)) { using (SQLiteCommand cmd = new SQLiteCommand(select)) { using (SQLiteDataAdapter sda = new SQLiteDataAdapter()) { cmd.Connection = con; sda.SelectCommand = cmd; cmd.CommandType = CommandType.Text; cmd.CommandTimeout = 9000000; cmd.Parameters.Add("@OrganisationId", DbType.String, 50).Value = txtOrgId.Text.ToUpper(); //cmd.Parameters.Add("@Month", DbType.String, 50).Value = cboMonthSearch.SelectedItem.ToString(); cmd.Parameters.Add("@Year", DbType.String, 50).Value = cboYearSearch.SelectedItem.ToString().ToUpper(); using (DataSet dsCustomers = new DataSet1()) { sda.Fill(dsCustomers, "DataTable2"); if (dsCustomers.Tables[1].Rows.Count == 0) { reportViewer1.Visible = false; MessageBox.Show("Records not found!"); } else { reportViewer1.Visible = true; } return dsCustomers; } } } } }
Событие нажатия кнопки:
private void btnShowReport_Click(object sender, EventArgs e) { errorProvider1.Clear(); if (txtOrgId.Text != "") { if (cboYearSearch.SelectedIndex != 0) { DataSet dsCustomers = GetData(); ReportDataSource datasource = new ReportDataSource("DataSet1", dsCustomers.Tables[1]); this.reportViewer1.LocalReport.DataSources.Clear(); reportViewer1.ProcessingMode = ProcessingMode.Local; // the ReportPath is relative to the page displaying the ReportViewer reportViewer1.LocalReport.ReportPath = "Report2.rdlc"; this.reportViewer1.LocalReport.DataSources.Add(datasource); this.reportViewer1.RefreshReport(); } else { errorProvider1.SetError(cboYearSearch, "Select Year!"); cboYearSearch.Focus(); } } else { errorProvider1.SetError(txtOrgId, "Enter OrgId!"); txtOrgId.Focus(); } }
Я буду признателен, если кто-нибудь сможет помочь в том, как сделать его отображение немного быстрее. Спасибо
CHill60
Я не понимаю, как вы вообще получаете какие-либо результаты, поскольку у вас есть элементы в SELECT, которые не являются агрегатными функциями и не входят в предложение GROUP BY
Uwakpeter
Запрос закончился за 0,046 секунды во время работы в окне запроса sqlite. у меня есть еще один оператор select, который не использует предложение group by, для его отображения все равно требуется столько же времени!
CHill60
Хорошо, я никогда раньше не использовал SQLite, но теперь я знаю, что он не придерживается стандартов T-SQL для группировки.
Однако если запрос выполняется за 0,046 секунды, то проблема должна быть связана с вашим отчетом. Есть ли у вас какие-либо расчеты или причудливое форматирование в вашем отчете?
Uwakpeter
Отчет имеет 35 столбцов, я использовал это: =IIF ((Fields!Dept. Value = "Nill"), true, false) для видимости столбцов, а также:
=FormatNumber(Поля!Transp. Value, 2) на 20 выражениях текстового поля, может ли это быть проблемой?
Richard Deeming
Раз уж ты возвращаешься dsCustomers
от вашего GetData
метод, вы же не хотите поместить его в using
блок.
Заменять:
using (DataSet dsCustomers = new DataSet1())
с:
DataSet dsCustomers = new DataSet1();
Ваш запрос возвращает только одну таблицу, поэтому непонятно, почему вы всегда обращаетесь ко второй таблице? (Помните, что коллекции используют индексацию на основе нуля, поэтому
Tables[1]
возвращает вторую таблицу.)Есть ли что-то странное в вашем обычае
DataSet1
класс? Вы пробовали использовать raw DataSet
вместо этого?
Uwakpeter
я попытался с помощью dsCustomers набор данных = новый набор данных 1(); но он по-прежнему занимает то же самое количество времени. Я использую таблицу[1], потому что у меня есть как шесть таблиц данных в одном наборе данных, шесть таблиц данных предназначены для разных отчетов, никакие два отчета не могут быть доступны одновременно.
Richard Deeming
Вам не нужен пользовательский набор данных с таблицами для всех ваших отчетов. Попробуйте использовать стандарт DataSet
вместо этого, с Tables[0]
вместо Tables[1]
.
Uwakpeter
да, я пробовал, кажется, теперь он отображается быстрее, но когда я добавил Эти строки кода: =IIF ((Fields!TIN. Value = "Nill"), true, false),=Max(Fields!Transp. Value + 0) = 0 И Min (Поля!Трансп. Значение + 0) = 0.
Чтобы в отчете скрыть некоторые столбцы, если они равны нулю или нулю, он снова стал очень медленным, пожалуйста, есть ли лучший способ скрыть столбец, чем этот?