65.9K
CodeProject 正在变化。 阅读更多。
Home

Cubes、MDX、Analysis Services 和 ADOMD in C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.20/5 (26投票s)

2004 年 3 月 30 日

viewsIcon

208213

downloadIcon

4120

一篇关于 .NET 中 Cubes、MDX、Analysis Services 和 ADOMD 的文章

引言

在网上搜索时,我发现了很多解决方案,但没有一个能正常工作。然后我考虑了 ADOMD.NET,但它仍处于 Beta 阶段,因此不建议使用。最终,我不得不主动出击,决定自己动手实现。

我使用了 Interop 来在 .NET 中完成这项工作。希望对某人有所帮助。这个应用程序将 MDX 查询作为输入,并在 Web 表单中呈现 HTML 表格作为输出。您需要将 ADOMD 2.7 和 ADODB 2.7 作为引用,并且需要包含它们才能使用。不要忘记写入以下两行

using ADODB;
using ADOMD;

代码非常简单,易于理解。

什么是 MDX?

MDX 是您在使用 OLAP 时必须了解的关键技术之一。MDX 可用于描述多维查询、定义立方体结构以及更改数据(在某些情况下)。让我们从概述 MDX 语句的基本形式开始

SELECT {member selection} ON COLUMN FROM [cube name]

示例查询

SELECT {[Store Type].MEMBERS} ON COLUMNS,
{[Store].[Store City].MEMBERS} ON ROWS
FROM [Sales]
WHERE (MEASURES.[Sales Average])

请记住,它与 SQL 分析服务的关系就像 TSQL 与 MS Sql 的关系一样。

webform1.aspx 的 HTML 代码

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" 
  AutoEventWireup="false" Inherits="Test2.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" 
  name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<TABLE id="Table1" style="Z-INDEX: 101; LEFT: 16px; WIDTH: 681px; 
  POSITION: absolute; TOP: 40px; HEIGHT: 128px" 
  cellSpacing="1" cellPadding="1" width="681" border="1">
<TR>
<TD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  &nbsp;&nbsp;&nbsp;&nbsp;
<asp:Button id="btnFire" runat="server" Text=">>>" 
  Width="85px" ToolTip="Press to Execute Query" 
  Font-Bold="True"></asp:Button></TD>
</TR>
<TR>
<TD>
<asp:TextBox id="txtQuery" runat="server" 
  TextMode="MultiLine" Width="671px" Height="94px" 
  ForeColor="Black"></asp:TextBox></TD>
</TR>
</TABLE>
<TABLE id="Table3" style="Z-INDEX: 103; LEFT: 338px; 
  WIDTH: 359px; POSITION: absolute; TOP: 168px; HEIGHT: 30px" 
  cellSpacing="1" cellPadding="1" width="359" border="1">
<TR>
<TD style="WIDTH: 78px"><STRONG>&nbsp;Dimensions</STRONG></TD>
<TD>
<asp:DropDownList id="cboDimns" runat="server" Width="261px" 
  AutoPostBack="True"></asp:DropDownList></TD>
</TR>
</TABLE>
<TABLE id="Table2" style="Z-INDEX: 102; LEFT: 15px; WIDTH: 297px; 
  POSITION: absolute; TOP: 168px; HEIGHT: 30px" cellSpacing="1" 
  cellPadding="1" width="297" border="1">
<TR>
<TD style="WIDTH: 323px"><STRONG>Cubes</STRONG></TD>
<TD>
<asp:DropDownList id="cboCubeList" runat="server" Width="268px" 
  AutoPostBack="True"></asp:DropDownList></TD>
</TR>
</TABLE>
</form>
</body>
</HTML>

C# 代码

using System;
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using ADOMD;
using ADODB;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Test2
{
    /// <summary>
    /// Summary description for WebForm1 
    /// Developed By Sanket Naik Emp Code 1550.
    /// </summary>
public class WebForm1 : System.Web.UI.Page
{
    protected System.Web.UI.WebControls.Button btnFire;
    protected ADODB.Connection con;
    protected System.Web.UI.WebControls.TextBox txtQuery;
    protected ADOMD.Cellset cset;
    protected System.Web.UI.WebControls.DropDownList cboCubeList;
    protected System.Web.UI.WebControls.DropDownList cboDimns;
    protected string constr = 
"Datasource=localhost; Provider=msolap; Initial Catalog=FoodMart 2000;";
#region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
        //
        // CODEGEN: This call is required by the ASP.NET Web Form Designer.
        //
        InitializeComponent();
        base.OnInit(e);
    }

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {    
        this.btnFire.Click += new System.EventHandler(this.btnFire_Click);
        this.cboCubeList.SelectedIndexChanged += 
          new System.EventHandler(this.cboCubeList_SelectedIndexChanged);
        this.Load += new System.EventHandler(this.Page_Load);

    }
#endregion

    private void btnFire_Click(object sender, System.EventArgs e)
    {
        try
        {

            string query = txtQuery.Text.ToString();
            con = new ConnectionClass();
            con.Open(constr,"sa","",0);
            cset = new CellsetClass();
            cset.ActiveConnection = con;
            cset.Open(query,con);
            int totColsLvl = 0; 
//total rows within column header (since cross joins may occur)

        totColsLvl = cset.Axes[0].Positions[0].Members.Count;  
        //Axes[0] represent column headers. Axes[1] represent row headers. 
        //Positions[0] represents the first position within the columns
        Response.Write("<Table id='Table1' style='Z-INDEX: 103; 
            LEFT: 120px; POSITION: absolute; TOP: 238px' cellSpacing='0' 
            cellPadding='2' width='600' border='1' bordercolor = '#000000' 
            bgcolor = 'WhiteSmoke' >");
      for (int i = 0;i < totColsLvl;i++)  //For each row in the column header 
      {
                Response.Write(
"<TR  bgcolor = 'Lightblue'> <TH > Rows </TH>"); //Start a row
                //Get all the header of the current row

                foreach (ADOMD.Position pos in cset.Axes[0].Positions)
                {   
                  Response.Write("<TH>" + pos.Members[i].Caption + "</TH>"); 
                  //Member[] holds the actual column data
                  //Caption returns the header caption to be displayed
                }
                Response.Write("</TR>"); //Close the row
            }   
            //              int totRowsLvl = 0; 
            //total rows within Rows header (since cross joins may occur)
            // 
            //              totRowsLvl = cset.Axes[1].Positions.Count;
            //              //Axes[1] is for Rows
            //              //Response.Write("<TD>"+ totColsLvl+"</TD>");
            //              for (int i = 0;i < totRowsLvl ;i++) 
            //For each row in the rows header 
            //              {
            //                  Response.Write("<TD>"); //Start a row
            //                  //Get all the header of the current row
            //                  Response.Write(
                    cset.Axes[1].Positions[i].Members[0].Caption); 
            //                  Response.Write("</TD>"); //Close the row
            //              }
            //Response.Write("</Table></TD>");
            int totCols =0;
            int totRows = 0;
            totCols = cset.Axes[0].Positions.Count; 
                //Total columns in the result
            totRows = cset.Axes[1].Positions.Count; 
                //Total rows in the result

            object[] coords = new object[2];  
            //Objects to hold the coordinates of the data being accessed
            for (int i = 0;i < totRows;i++) //For each row in the result
            {
                Response.Write("<TR>");  //Start table row
                Response.Write("<TD bgcolor = 'LightBlue'><b>" + 
cset.Axes[1].Positions[i].Members[0].Caption+ "</b></TD>"); 
                for ( int j = 0;j < totCols; j++) 
                     //In each row, for each column
                {               

                    //Initialize the coordinates of the data to be fetched
                    coords[0] = j;  //column
                    coords[1] = i;  //row

                    //get_Item fetches the data. 
                    ADOMD.Cell newcell;
                    newcell = cset.get_Item(ref coords);
                    object dispvalue;
                    dispvalue = newcell.FormattedValue;

                    if ( newcell.FormattedValue != null)                  
                    {
                        //display data
                        Response.Write("<TD>" + dispvalue + "</TD>");
                    }
                    else
                    {
                        Response.Write("<TD> 0 </TD>");
                    }


                }
                Response.Write("</TR>"); //Close the row
            }

            Response.Write("</Table>");
        }
        catch(Exception ex)
        {
            txtQuery.Text = ex.Message;
        }
    }

    private void Page_Load(object sender, System.EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            try
            {
                con = new ConnectionClass();    
                con.Open(constr,"sa","",0);
                ADOMD.Catalog ct = new Catalog();
                ct.ActiveConnection = con;
                int totalcubes = 0;
                totalcubes = ct.CubeDefs.Count;
                for(int i = 0; i < totalcubes; i++)
                {
                    cboCubeList.Items.Add(ct.CubeDefs[i].Name);
                }
            }
            catch(Exception ex)
            {
                txtQuery.Text = ex.Message;
            }
            finally
            {
                con.Close();
            }
        }
    }

    private void cboCubeList_SelectedIndexChanged(
         object sender, System.EventArgs e)
    {
        try
        {
            con = new ConnectionClass();    
            con.Open(constr,"sa","",0);
            ADOMD.Catalog ct = new Catalog();
            ct.ActiveConnection = con;
            int totalcubes = 0;
            totalcubes = ct.CubeDefs.Count;
            for(int i = 0; i < totalcubes; i++)
            {
                if (cboCubeList.SelectedItem.Text == ct.CubeDefs[i].Name)
                {
                    cboDimns.Items.Clear();
                    int cntDim = 0;
                    cntDim = ct.CubeDefs[i].Dimensions.Count;
                    for(int j = 0; j <cntDim ; j++)
                    {
                       cboDimns.Items.Add( ct.CubeDefs[i].Dimensions[j].Name);
                    }
                }
            }
        }
        catch(Exception ex)
        {
            txtQuery.Text = ex.Message;
        }
        finally
        {
            con.Close();
        }

    }

}
}
© . All rights reserved.