1

我的公司有一个 Windows 窗体应用程序,它利用 ClickOnce 和 .NET Remoting(即将成为 WCF)到处理所有数据访问操作的后端 IIS Web 应用程序。对于报告,我们目前使用 SSRS 并让分布式客户端直接连接到报告服务器。

我们希望能够通过 RDLC 文件支持本地报告,从而潜在地消除或增加我们对 SSRS 报告的依赖。我必须克服的一个障碍是单个客户端计算机不太可能直接访问数据库,因此需要通过我们的远程处理或 WCF 传输层从 Web 应用程序获取报告数据。

“发现”报告的参数以动态构建报告参数提示的 UI,我认为这并不难,但实际上告诉后端系统调用什么类/方法以返回正确的数据报告没有那么简单。

有没有人尝试过以某种方式将信息嵌入到 RDLC 文件中(通过报告中的注释或其他方式),这些信息可以用作服务器应用程序层的“提示”以确定执行什么方法?实际的 RDLC 很可能会存储在数据库中,而不是与我们的应用程序一起分发。

任何见解或指导将不胜感激。

-MrB

4

1 回答 1

1

查看www.gotreportviewer.com和 RDL 查看器示例(右侧的最后一个示例)。它已经具有加载 RDLC 和解析 XML 文件以获取参数以及连接信息和查询信息的代码。有了它,您应该能够使用后端来获取所有内容并填充/加载报告并运行它。

至于在某处的 RDLC 中添加提示或注释以指定要进行的调用,我建议也许只是使用报告名称作为提示。我们过去这样做是为了让我们的报告知道调用什么来加载数据。

我们以前做过这样的事情:

VB版:

Select Case GetReportName()

            Case "SiteEval"
                Using adp As New DataSetsTableAdapters.SiteEvalTableAdapter, _
                 objDT As New DataSets.SiteEvalDataTable
                    adp.Fill(objDT)
                    objLR.DataSources.Add(New ReportDataSource("DataSets_SiteEval", objDT))
                End Using
            Case ....

C#版本:

switch (GetReportName()) {

    case "SiteEval":
        using (DataSetsTableAdapters.SiteEvalTableAdapter adp = new DataSetsTableAdapters.SiteEvalTableAdapter()) {
            using (DataSets.SiteEvalDataTable objDT = new DataSets.SiteEvalDataTable()) {
                adp.Fill(objDT);
                objLR.DataSources.Add(new ReportDataSource("DataSets_SiteEval", objDT));
            }
        }

        break;

利用我们的 XSD 和数据集来加载我们的报告。在这种情况下,我们的本地报告可以访问数据库。在您的情况下,您可以采用这个想法,并使用您自己从服务调用返回的数据表填充数据集。如果您有大量报告,这不是最优雅或最容易维护的。

在我们的例子中,我们现在使用 RDL Viewer 示例并根据我们的需要对其进行修改,这样就不需要上面的代码了。我们将只传递 RDLC 文件的路径,代码将通过读取 RDLC 的 xml 来加载所需的内容。但是,在这种情况下,本地报告可以访问数据库。我认为修改它以从外部来源获取数据并不难,要么使用上述代码理念,要么像我们现在所做的那样从www.gotreportviewer.com修改 RDL Viewer 示例。

随着 RDL Viewer 示例的修改,我们现在有一些类似的事情(仍在解决......)代码在 VB 中。

    Dim r As New Report(Server.MapPath("App_Reports/" & GetReportName() & ".rdlc"), GetReportName())

    Dim p As ReportParameterInfoCollection = r.GetParameters() 'read only....
    If p.Count > 0 Then
        Dim rptParams(p.Count - 1) As ReportParameter
        Dim i As Integer = 0
        For Each param In p
            rptParams(i) = New ReportParameter(param.Name)
            rptParams(i).Values.Add("99999999")
            i += 1
        Next
        r.SetParameters(rptParams)
    End If

    r.LoadReport()

再见丑陋而冗长的 switch 语句。再见需要知道如何加载报告......现在,如果我们能弄清楚如何更好地处理参数......这个代码是当前正在进行的工作,但是 RDL Viewer 示例让我们快速开始...... ..

我也在玩反射做同样的事情。我发现这篇文章使反射工作变得轻而易举。 http://www.slimee.com/2009/09/net-using-reflection-to-execute.html

现在您要做的就是传入数据表的字符串,它将生成驱动报告的数据表。由于使用数据集,您将始终知道它如何创建您可以轻松使用的名称。

我认为这两种方法都是消除丑陋的 switch 语句并使代码更易于维护的解决方案。通过反射,代码会小得多,但可能会慢一些。

两者都有一些神奇的字符串问题。沿着这条线的某个地方,你必须传递你想要运行的字符串。一个团队可以轻松创建一个可以轻松解决的约定......

于 2010-08-24T13:58:07.027 回答