在微软的Report Services的rdl中,默认是支持从分许服务的Cube中查询数据的,但是rdlc中就需要间接的方式来对Cube的数据进行访问。
相对rdl和rdlc两者完全就是不同的套路。两者的差别绝对不是名字上只差个c那么简单,从设计的部分细节和部署的方式都有很大的区别。而实际项目中往往根据不同的情况来具体决定才用哪一种方案。
这里推荐用两种方式来访问。
第一种方式是用链接的形式将分析服务数据库链接到数据引擎服务,然后mdx查询的逻辑写到存储过程里,最后顶层应用通过调用存储过程的方式来间接达到访问分析服务数据库的目的。
另外一种方案就是将数据源用方法封装起来。由于rdlc本身是在一个c#或者vb.net项目中的,所以在rdlc中是支持把项目的一个方法作为数据源,这样可以在方法里对 adomd.net进行调用,然后将mdx结果以List的方式返回给rdlc。
第一种方法的具体实现可以参考sqlserver链接服务器的操作,这里主要描述第二种方法。
安装SQLServer,过程可以参考这里。
http://www.cnblogs.com/aspnetx/archive/2012/04/13/2446479.html
这里推荐安装2012版本。不考虑2012里的新特性的话,基本上你不用太担心先前版本能否迁移过来。
下载示例数据文件。
从codeplex下载。
DW文件:
http://msftdbprodsamples.codeplex.com/downloads/get/165405
SSAS脚本文件:
http://msftdbprodsamples.codeplex.com/downloads/get/258486
由于本文用到的Cube取自微软官方SQLServer示例中的Adventure Works示例库,而SSAS数据库只提供项目文件,所以需要同时下载DW文件以供SSAS去处理。
需要留意一下的是下载的是DW数据库,而不是OLTP数据库,这两个库在结构上有很大的差别,不要下载错。
首先将下载下来的数据库文件附加进数据引擎服务。
打开SSAS脚本文件。
可以看到VS2010设计器被打开。(话说等这个等了好久。。。)
如果你有装VS2012,这里需要右键选择用VS2010来打开。
右键项目,处理一下SSAS数据库。
处理过程跟先前的版本没什么大的区别。
接下来,假如我们要在rdlc中显示如下的mdx语句的查询结果。
RDLC中读取Analysis Services中Cube的数据
新建一个asp.net webapplication项目。
项目中加入一个页面来承载report viewer控件,再加入一个类,里面封装方法供rdlc报表使用,此外还需要加入一个rdlc报表定义文件。
特别说明一下,无论是rdl或者rdlc在asp.net和winform程序中都可以通过report viewer控件集成进来的。
还需要填加一个引用,adome.net,一个类似ado.net的类,不同的sqlserver有不同的版本,针对sqlserver2012,版本为11。如果是默认安装的话那么可以在如下目录中找到这个要引用的dll。
C:\Program Files\Microsoft.NET\ADOMD.NET\110
首先定义一个类,这个类跟MDX的返回结果是对应的,针对前面提到的mdx语句,定义如下类。
public class DataItem
{
public string RowTitle { get; set; }
public double Value1 { get; set; }
public double Value2 { get; set; }
}
然后编写方法,这个方法将作为后面rdlc报表的数据源。
public static List<DataItem> GetData()
{
List<DataItem> result = new List<DataItem>();
AdomdConnection conn = new AdomdConnection();
conn.ConnectionString = "Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=AdventureWorksDW2012Multidimensional-EE;Data Source=.";
conn.Open();
StringBuilder sbMDX = new StringBuilder();
sbMDX.AppendLine("WITH ");
sbMDX.AppendLine("MEMBER [Measures].[Sale Amount Ratio] AS '[Measures].[Internet Sales Amount]/([Measures].[Internet Sales Amount], [Product].[Product Categories].[All])' , FORMAT_STRING = '0.00%' ");
sbMDX.AppendLine("SELECT ");
sbMDX.AppendLine("{[Measures].[Internet Sales Amount], [Measures].[Sale Amount Ratio]} ");
sbMDX.AppendLine("ON 0,");
sbMDX.AppendLine("NON EMPTY [Product].[Product Categories].[Product].MEMBERS ");
sbMDX.AppendLine("ON 1");
sbMDX.AppendLine("FROM [Adventure Works]");
AdomdCommand comm = new AdomdCommand();
comm.Connection = conn;
comm.CommandText = sbMDX.ToString();
AdomdDataReader dr = comm.ExecuteReader();
while (dr.Read())
{
DataItem di = new DataItem();
di.RowTitle = dr[0].ToString() +"-"+ dr[1].ToString() +"-"+ dr[2].ToString();
di.Value1 = double.Parse(dr[3].ToString());
di.Value2 = double.Parse(dr[4].ToString());
result.Add(di);
}
return result;
}
}
由于用到了adomd.net对象,所以需要加入如下引用:
using Microsoft.AnalysisServices.AdomdClient;
打开Report.rdlc
在Report Data中选择新建-数据集,上面的数据集属性窗体会被打开,在Data source里可以找到当前建立的程序命名集空间名称,选择它,然后在Avaliable dataset里就可以看到刚才建立的方法。选择它,可以看到数据集的结构。
接下来简单设计下这个报表。
最后回到Default.aspx页面,加入ReportViewer控件。在Visual Studo 2008之后的版本,还需要填加Script Manager控件。
在控件里选择项目中的报表。可以看到一个ObjectDataSource控件被加到页面上,Visual Studio会根据报表里的数据源来自动填加数据源控件。
最后,直接运行项目,就可以看到报表的最终样式。在rdlc中不像rdl没有预览功能,所以只能在承载的页面里看报表的结果。
可以看到MDX的结果被显示了出来。
关键点:
Rdlc可以识别出项目中的方法,以此来作为其自身的数据源。
承载aspx的页上,通过ObjectDataSource将类方法映射到rdlc的数据源定义中。
总结:
这种方法相对于rdl或者链接服务器的方法,比较绕,但是从另一个角度来说,也有一些优势。
1. 不需要reporting services承载。
2. 复杂的逻辑可以封装到c# code中,对于开发复杂报表会容易并且方便调试。
3. 不仅MDX,也适用于挖掘模型以及DMX的查询。