Uwakpeter Ответов: 0

Генерация отчетов 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.

Чтобы в отчете скрыть некоторые столбцы, если они равны нулю или нулю, он снова стал очень медленным, пожалуйста, есть ли лучший способ скрыть столбец, чем этот?

0 Ответов