【问题标题】:Best practices for using RDLC in a distributed environment在分布式环境中使用 RDLC 的最佳实践
【发布时间】:2010-08-24 13:51:18
【问题描述】:

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

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

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

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

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

-MrB

【问题讨论】:

    标签: rdlc dynamic-rdlc-generation


    【解决方案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 查看器示例后,我们现在有一些类似的事情(仍在解决中......)代码在 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 语句并使代码更易于维护的解决方案。通过反射,代码会小得多,但可能会慢一些。

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

    【讨论】:

    • 这个例子看起来很有用。我将不得不对 RDL 模式进行更多研究,以便了解“条件”参数是如何表示的。至于“提示”,我对使用一些巨大的 switch 语句持怀疑态度,宁愿做更通用的事情。我想我可以检查 RDL 以获取查询并执行它们并将结果数据集发回。
    • 这正是我目前正在尝试做的......摆脱巨大的 switch 语句。我有两件事。首先是上面提到的选项,带有来自 gotreportviewer 的示例并读出 RDLC 模式。我现在有一个示例,它只传递了 RDLC 的路径和文件名以及我的参数,其余的就会神奇地发生。我也在考虑在上面的代码示例中使用反射来传递一个字符串来运行和加载/运行代​​码,而无需切换。
    • 我现在还添加了如何使用反射来执行此操作....不确定我们将采用哪种方式,但反射示例非常简洁,我们不会遇到速度和/或信任问题问题。
    猜你喜欢
    • 1970-01-01
    • 2016-02-11
    • 2015-07-25
    • 1970-01-01
    • 2010-11-19
    • 2016-06-24
    • 1970-01-01
    • 2021-04-27
    • 1970-01-01
    相关资源
    最近更新 更多