1

我正在使用 VS2010 和内置的可视报表设计器创建 RDLC 模板,用于使用 ReportViewer 控件和 .LocalReport 成员在 ASP.NET 应用程序中将带有子报表的报表呈现为 PDF 文件。代码遍历一组记录,为每条记录生成一个报告(及其子报告)。

我最近注意到,对于少数报告,其中一个子报告失败并给出“错误:无法显示子报告”消息。这个案例让我感到困惑的是,与我读过的许多关于这个错误的帖子(以前我自己也曾与它搏斗过)相比,它只发生在一小部分案例中;从我在其他地方看到的情况来看,问题通常是全有或全无——这个错误总是出现,直到找到解决方案,然后这个错误永远不会出现。

那么......什么可能导致仅记录的子集出现此错误?我可以直接运行有问题的子报告而不会出错;我可以打开 .xsd 文件并预览违规记录的 DataSet 而不会出错;我可以在 SQL Server Mgt Studio 中运行 DataSet 后面的查询而不会出现错误...我不确定在哪里可以找到这个问题的原因,它只在我运行带有子报表的报表时出现?

4

1 回答 1

1

我将其追踪到了一个过时的 .xsd 文件(DataSet)——在某处增加了表列字符串的宽度,但 DataSet 没有更新或重新生成,所以它仍然有旧的宽度限制元素,例如 .xsd XML 中的 <xs:maxLength value="50" /> 而不是 125 个字符的新宽度。如果子报表中至少有一条记录在该列中的数据值(字符串)超过旧的 50 宽度,则会引发错误。

一个重要的线索来自为 DataSet 的 .Selected 事件添加一个处理程序;我已经在使用 .Selecting 事件来设置子报告的参数(将其绑定到父记录),但是在中断该事件时我看不到任何有用的东西。但是,检查 .Selected 事件中的事件 args 变量,在应该发生选择之后,我发现一个异常(“调用的目标已引发异常”)和一个 InnerException(“无法启用约束。一个或更多行包含违反非空、唯一或外键约束的值”)。还有一个堆栈跟踪表明故障点正在执行 Adapter.Fill(dataTable)。

虽然这很容易引起误解——我在 DataSet 后面的查询中涉及的表上没有这样的限制——但它至少让我专注于子报表中的特定记录。在子报表记录数据 SQL Server Mgt Studio 中搜索异常无果后,我最终开始从一个有问题的子报表案例中逐一删除记录,每次都重新运行报表以查看是否已修复错误. 最终我删除了一个子报表记录并且报表工作了——剩下的子报表记录出现了!

现在我有一个特定的子报告记录可以更仔细地检查。一次偶然的机会(希望我可以称它为启发式直觉......),我决定在 Web 应用程序中编辑该记录,而不是像在 SQL Server 中那样查看它。其中一个字段被标记为警告,提示字符串值太长!这让我一时疑惑:如果字符串值太长,怎么可能已经保存在数据库中了?!我仔细检查了表中的列定义,发现它比 Web 应用程序前端试图强制执行的要长。然后我意识到该列在没有更新应用程序 UI 的情况下被扩展,我立即怀疑 .xsd 文件也没有更新......宾果游戏!

这个故事可能有很多道理,它让我有一种熟悉而又不受欢迎的感觉,我没有像我应该做的那样聪明地做一些事情。一个寓意:每当您更改其基于的查询或表时,始终更新(或者更好,通常更简单,只需重新构建)您的 .xsd 数据集文件......但是,说起来容易做起来难。我有一种不安的感觉是,一定有一些我没有想到的方法来避免构建脆弱的应用程序,其中在数据库中定义的列宽也单独编码到 UI 和/或代码隐藏以提供用户反馈和/或进行数据验证...欢迎提出有关如何更稳健地管理的建议!

于 2013-04-04T03:59:54.907 回答