在客户端程序中通过MDX查询SSAS的数据
这两天在讲解SSAS(SQL Server Anaylysis Service)及其编程。其中有一个话题就是,如何将SSAS的查询结果,显示在我们自定义的应用程序里面。
关于SSAS,是微软在商务智能(BI)平台上的一个最重要的组件,称为分析服务器。如果你还不熟悉,可以先参考这里
课堂上有一个小例子,演示了如何编写程序实现简单的查询。整理出来给有兴趣的朋友参考一下
有几个要点
1。客户端与SSAS的通讯,其实传递是XML/A指令。发起这种指令,可以通过标准的Web Request(封装为一个SOAP包即可),也可以通过客户端API。
2。SQL Server 自带了一个客户端API,Microsoft.AnalysisServices.AdomdClient.dll.这个程序集,一般是在C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\100\Microsoft.AnalysisServices.AdomdClient.dll 这个路径下面。(备注,我是使用64位系统,SQL Server的版本是SQL Server 2008 R2)
3。使用Adomd的方式与标准的ADO.NET还是有相似之处的,也需要有Connection以及Command之类的对象,只不过它的查询语法是所谓的MDX(多维表达式),而且它返回的结果不是一个平面的二维结构,可能会有多个轴(最多可以有128个轴),所以解析的时候会更加复杂些。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Microsoft.AnalysisServices.AdomdClient; namespace WindowsFormsApplicationSSASClient { public partial class Form1 : Form { public Form1() { InitializeComponent(); Load += new EventHandler(Form1_Load); } void Form1_Load(object sender, EventArgs e) { using (var conn = new AdomdConnection("Data Source=localhost;Catalog=Adventure Works DW 2008;")) { using (var cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT [Customer].[Customer Geography].[Country] ON 0,[Product].[Product Categories].[Category] ON 1 FROM [Adventure Works]";//这里使用的是MDX语法 conn.Open(); var result = cmd.ExecuteCellSet();//这是返回一个特殊的CellSet对象,因为SSAS的结果集可能是有多维的 var tb = ToDataTable(result);//通过一个标准方法将CellSet转换为DataTable dataGridView1.DataSource = tb; } } } public DataTable ToDataTable(CellSet cs) { DataTable dt = new DataTable(); dt.TableName = "resulttable"; DataColumn dc = new DataColumn(); DataRow dr = null; //第一列:必有为维度描述(行头) dt.Columns.Add(new DataColumn("Description")); //生成数据列对象 string name; foreach (Position p in cs.Axes[0].Positions) { dc = new DataColumn(); name = ""; foreach (Member m in p.Members) { name = name + m.Caption + " "; } dc.ColumnName = name; dt.Columns.Add(dc); } //添加行数据 int pos = 0; foreach (Position py in cs.Axes[1].Positions) { dr = dt.NewRow(); //维度描述列数据(行头) name = ""; foreach (Member m in py.Members) { name = name + m.Caption + "\r\n"; } dr[0] = name; //数据列 for (int x = 1; x <= cs.Axes[0].Positions.Count; x++) { dr[x] = cs[pos++].FormattedValue; } dt.Rows.Add(dr); } return dt; } } }