#asp.net #crystal-reports
#asp.net #crystal-отчеты
Вопрос:
Мы запускаем веб-приложение для создания отчетов, которое позволяет пользователю выбирать несколько полей, и на основе выбранных полей генерируется crystal report. SQL, сгенерированный для самого сложного отчета, вернет данные менее чем за 5 секунд, однако на выполнение отчета уходит в среднем 3 минуты, иногда дольше, что приводит к тайм-ауту. Мы используем VS2010. Отчеты в основном настраиваются «из коробки» без каких-либо реальных манипуляций или вычислений, просто отображая данные в удобном формате. Можем ли мы попытаться ускорить это, предварительно загрузив фиктивный отчет для загрузки DLL, какой-нибудь хак, чтобы ускорить работу crystal, что угодно?
РЕДАКТИРОВАТЬ: Добавлен код для отображения привязки данных
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
string strFile = Server.MapPath(@"AwardStatus.rpt");
CrystalReportSource1.Report.FileName = strFile;
DataTable main = Main();
CrystalReportSource1.ReportDocument.SetDataSource(main);
CrystalReportViewer1.HasCrystalLogo = false;
CrystalReportSource1.ReportDocument.ExportToHttpResponse(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, Response, false, "pmperformance");
}
}
private DataTable Main()
{
Guid guidOffice = Office;
CMS.Model.ReportsTableAdapters.ViewACTableAdapter rptAdapter = new CMS.Model.ReportsTableAdapters.ViewACTableAdapter();
Reports.ViewAwardedContractsDataTable main = new Reports.ViewAwardedContractsDataTable();
if (Office == new Guid())
{
IEnumerable<DataRow> data = rptAdapter.GetData().Where(d => UserPermissions.HasAccessToOrg(d.guidFromId, AuthenticatedUser.PersonID)).Select(d => d);
foreach (var row in data)
{
main.ImportRow(row);
}
}
else if (guidOffice != new Guid())
{
main = rptAdapter.GetDataByOffice(guidOffice);
}
else
{
main = new Reports.ViewACDataTable();
}
return main;
}
private Guid Office
{
get
{
string strOffice = Request.QueryString["Office"];
Guid guidOffice = BaseControl.ParseGuid(strOffice);
if (!UserPermissions.HasAccessToOrg(guidOffice, AuthenticatedUser.PersonID))
{
return Guid.Empty;
}
else
{
return guidOffice;
}
}
}
protected void CrystalReportSource1_DataBinding(object sender, EventArgs e)
{
//TODO
}
Комментарии:
1. Как вы привязываете данные к отчету? Можете ли вы опубликовать код, который генерирует отчет?
2. Если вы пройдетесь по этому коду, зависнет ли он в какой-либо момент? Похоже, вы выполняете изрядную часть обработки для DataTable.
3. @Barry — нет, кажется, что все выполняется довольно быстро, никаких реальных зависаний, о которых нужно предупреждать.
4. Какого размера файл отчета? Сохраняется ли вместе с отчетом большой объем данных, что может привести к увеличению времени загрузки из-за размера файла?
Ответ №1:
Это может показаться немного легкомысленным, но, возможно, стоит отказаться от использования crystal reports… Недавно у нас были с ними изрядные проблемы (одна из них — ошибка нехватки памяти), и мы перешли к другим вариантам и вполне довольны…
Комментарии:
1. мы склоняемся к этому, если мы не можем устранить некоторые из этих недостатков, к чему вы перешли, что вам нравится?
2. Я и раньше с некоторым успехом пользовался MS Reporting Services, но в этом случае нам нужны были PDF-файлы, и мы обратились к написанию собственных с помощью iTextSharp — немного кривой обучения, но выводим точно так, как требуется, и очень быстро. И больше никаких разочарований дизайнера crystal reports.
3. Не знаю, имеет ли это значение, но уровень поддержки MS для CR, похоже, снижается: blogs.msdn.com/b/vbteam/archive/2010/04/08 /…
Ответ №2:
Вот что я бы сделал:
Установите часы с момента получения пользователем выбора полей вплоть до момента отображения отчета. Посмотрите, насколько увеличивается время обработки.
Когда вы смотрите на часы, могут возникать различные ситуации:
-
Если Crystal Reports требует времени для заполнения отчета, проверьте, как вы его заполняете. Если вы связываете поля отчета непосредственно с вашей таблицей данных, CR, вероятно, тратит время на поиск данных. Я предлагаю создать новую таблицу (t_rpt) с динамическими столбцами (Field1, Field2, ..FieldN) и указать ваш шаблон отчета на эту таблицу. Я не знаю, делаете ли вы это уже.
-
Если вам требуется время для поиска самих данных, я предлагаю создать представление вашей таблицы. Несмотря на большой объем памяти, это ускорит поиск, и вы сможете удалить представление, как только закончите.
Если ничего из вышеперечисленного нет, сообщите нам, что показывают ваши часы.
Ответ №3:
Что касается загрузки любого большого объема данных, вы всегда захотите использовать хранимую процедуру.
Помимо этого, вы увидите задержку в отчете, выполняемом при первой загрузке библиотеки DLL Crystal. Да, вы можете предварительно загрузить их, как вы упомянули, и это немного поможет.