(我是一位拥有25年以上经验的开发人员,但是我对SSRS还是很陌生,因此我正在努力更好地理解一些基础知识。)
子报告。
到目前为止,我所读的一切都是将子报表创建为独立的.rdl或.rdlc文件,然后将该文件链接到主报表中。那部分很有意义。
但是,在寻求有关如何有效执行此操作的帮助时,我看到了在教程中重复的相同模式:使用未过滤的SELECT语句(无参数或WHERE子句)作为数据源,然后使用过滤器来限制根据需要显示数据。
我只需要了解一件事。这是“最佳且唯一”的方式,还是这是一种最容易解释但实际上在负载下表现惊人的有效方式的示例?严重的是,没有人期望NorthWind或AdventureWorks是复杂数据流的真实示例。
我们正在为客户端编写此报告,该客户端具有成千上万的行,这些行将在未经过滤的SELECT语句中返回,但是如果我可以基于WHERE子句使用正确的SELECT语句,则最多返回10行从主报表传递到子报表的参数。我还不知道该报告的响应时间是多少,但是如果要为子报告获取并处理成千上万的行,那么速度将非常糟糕。
有人可以引导我进入讨论有效处理SSRS子报表的博客或其他资源吗?
答案 0 :(得分:0)
我只能得出结论,到目前为止,我发现的所有教程都提供了过于简化的解决方案,这些解决方案根本无法很好地扩展。
我很幸运地选择了一个线程来处理另一个问题,但是OP提出了他的解决方案,那就是exactly what I needed。
总结一下: 1)因为子报告只是一个.rdlc,所以根本没有进行预处理的空间。任何预处理都必须在主报表的.ASPX.CS代码中进行处理。
2)在.ASPX.CS Page_Load中,向您的ReportViewer添加一个新的SubreportProcessingEventHandler,例如:
yourReportViewer.LocalReport.SubreportProcessing += new
SubreportProcessingEventHandler(SetSubDataSource);
yourReportViewer.LocalReport.Refresh();
3)在EventHandler中,建立数据库连接,然后仅取回子报表所需的数据。您无需全部获取,然后对其进行过滤,这是非常低效的。
public void SetSubDataSource(object sender, SubreportProcessingEventArgs e)
{
// Reload the data required
SqlConnection conn = null;
SqlCommand cmd = null;
conn = new SqlConnection();
conn.ConnectionString =
ConfigurationManager.ConnectionStrings["connectionStringFromWebConfig"].ConnectionString;
conn.Open();
cmd = new SqlCommand();
cmd.Connection = conn;
SqlDataAdapter dataAdapter = new SqlDataAdapter();
DataSet dataset = new DataSet();
if (e.ReportPath == "yourSubReport")
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "yourSubReportStoredProcedure";
cmd.Parameters.AddWithValue("@subReportParam1", subReportParam1.Text);
dataAdapter = new SqlDataAdapter(cmd);
dataAdapter.Fill(dataset);
e.DataSources.Add(new ReportDataSource("yourSubReportDataSetName", dataset.Tables[0]));
}
}