是否可以将报表数据集作为方法参数传递给 SSRS 2008 或更高版本中的自定义程序集?

Is it possible to pass a report dataset as a method parameter to a custom assembly in SSRS 2008 or above?

TL;DR 在使用自定义程序集进行一些额外计算的 SSRS 2008 报告中,我可以将整个报告数据集作为方法参数传递吗?

全文

我有一个包含 3 个数据集的 SSRS 报告,每个数据集 return 来自 SQL 查询。
(如果这对我的问题有影响,它们目前是共享数据集,尽管我确定本地也可以)

最大的主要数据集是可能已完成或未完成的任务列表。我在这里有每个任务的 ID、状态、创建 date/time、目标解决时间等信息。 此数据集显示在 tablix 中,是报告的重点。

剩下的两个数据集就不展示了,仅供参考。一个是简单的单列查询,其中 return 是英国的假期日期列表。另一个是一个小 table,其中包含我们确切的营业时间。

目前,我能够遍历任务 tablix 中的行,并将当前行中的多个值传递给方法。如果我想根据仅在当前行中找到的数据进行一些计算,这将很有用。例如,我可以采用创建 date/time 和响应目标小时数,程序集将为当前任务 return 目标 date/time。到目前为止很酷。

我想做一个更复杂的版本,我不仅传递行数据,还传递其他 2 个数据集来获取我的 return 值。这是因为实际上截止日期的计算要复杂得多,并且必须考虑其他 2 个数据集不断变化的营业时间和假期。

我可以将数据集作为方法参数传递给程序集吗?类似于:
=Code.MyClass.MyMethod(val1, val2, dataset1, dataset2);.

我一直无法找到关于此的更多权威信息。几乎所有教程都通过处理单行来演示我已经在做什么。我确定我有一篇 MSDN 文章暗示这是不可能的,但我把它弄丢了(我知道这很有帮助)。有一个 post on the Microsoft forums 版主说这是不可能的。普遍缺乏信息和教程表明这是不可能的,或者我以错误的方式这样做。

有什么建议吗?

(我有其他解决方案,例如让程序集获取其他数据集,或者只是在 SSRS 之外编写一些东西,但在我知道是否可以通过这种方式完成之前,我不会追求这些)。

MSDN 论坛上的一个较旧的主题 Iterate through rows of dataset in report's custom code 提供了更明确的答案以及该问题的潜在解决方案。

不可能将数据集作为对象或集合传递,因为:

A dataset in Reporting Services is not the same type of object as an ADO.Net dataset. A report dataset is an internal object managed by the SSRS runtime (it's actually derived from a DataReader object) and not an XML structure containing datatables, etc. and cannot be passed into the report's custom code.

The only way to effectively loop through the rows of a report dataset is to call a custom function or referenced method in a report data region expression. Using this technique, it may be possible to pass all of the the row and field information into a code structure, array or collection.

上述语句中给出的提示建议将行和字段信息传递到代码结构中。作为链接的 MSDN 主题的贡献者,Migeul Catalao 使用这种方法开发了一种解决方法。

可以找到使用示例代码演示 Migeul Catalao 解决方案的真实场景 here

当然,它更像是一种逐行方法,因此我强烈建议脱离 SSRS 并寻求替代解决方案。

虽然我已经接受了另一个答案,因为它清晰且有用,但我最终没有使用那个解决方案(我太笨了,无法理解它)并选择了其他有用的东西。

免责声明:这是一个可怕的黑客攻击。它在我的场景中工作得非常好,所以我会分享以防它对其他人有用。这里有很多陷阱,很可能在给定的时间内解决。

我最终听从了 Steven White 评论中的建议并调查了 LookupSet。此函数允许您查询数据集以 return 匹配行和 单列数据 .

看起来像这样:

LookupSet(Fields!ComparisonField.Value,   // The value to search for, e.g '001'.
          Fields!MatchField.Value,        // The column to match on in the target dataset.
          Fields!MyColumn.Value,          // The column that will be returned.
          "MyDataSet")                    // The dataset to search.

这 return 是一个字符串数组,表示 returned 值。

到目前为止一切顺利,但我需要所有的列和行。这是以字符串连接的形式出现的脏 hack:

LookupSet(0,                             // Dummy ID 0.
          0,                             // Matches the dummy ID 0 so all rows are returned.
          Fields!Column1.Value + "[^]"   // I concatenate all of the values into
        + Fields!Column2.Value + "[^]"   // one string with the separator [^]
        + Fields!.Column3.Value,         // so I can split them later.
          "MyDataSet")                   // The dataset to query

我现在可以将其传递给我的自定义程序集:

=MyAssemblyNamespace.Class.Method(LookupSet(0,0,Fields!Column1.Value..., "MyDataSet"), other, parameters, here)

现在在我的 C# 方法中我有一个通用对象,经过一些反射后它实际上是一个字符串数组。

投射到有用的东西:

var stringList = ((IEnumerable)MyDataSetObject).Cast<string>().ToList();

拆分:

foreach (var item in stringList)
{
    var columns = item.Split(new[] { "[^]" }, StringSplitOptions.None);

    // columns is a string[] which holds each column value for the current row
    // So columns[0] is the value for column 1 in this row
    // In my case I pushed the values to a DataTable row each time and built a datatable 
    // which when finished represented my dataset in full with all rows and columns.
}

我希望这对任何试图获得类似结果的人都有意义。