一、問題的提出
在利用MDX查詢Cube的時候,經常會遇到這樣一種情況,行軸或列軸含多個維度(CrossJoin),CellSet返回了多個維度成員的值,在將CellSet轉成DataTable的時候,我們希望能返回這些維度成員的值。而利用網上搜尋到的方法,如前文“FusionChart對MDX查詢結果的資料展示案例”所述,是不能滿足該功能的。
具體問題如下面圖一和圖二所示:
圖一 MDX查詢時列軸有兩個維度CrossJoin
圖二 用之前的CellSet轉DataTable方法後維度成員資訊被拼在了一起 二、目標 我們希望得到圖一所示的DataTable,即所有維度均作為列或者行返回。如三所示:圖三 期待的DataTable結果 三、改進方案 這裡需要考慮兩個問題:(1)Crossjoin的維度個數可能有2個及以上,改進後的代碼要適應任意多個維度情況;(2)要滿足行列反轉的情況(DataTable的列名不能重名);其實也很簡單,改進後的代碼如下: /// <summary>
/// 將CellSet轉化成DataTable(包括所有維度)
/// </summary>
/// <param name="cs">CellSet</param>
/// <returns></returns>
public DataTable ToDataTable(CellSet cs)
{
DataTable dt = new DataTable();
dt.TableName = "ResultTable";
DataColumn dc = null;
DataRow dr = null;
//產生資料列對象
//多個維度轉化成列
for (int col = 0; col < cs.Axes[1].Set.Hierarchies.Count; col++)
{
dc = new DataColumn();
//下面的代碼會報錯:"The connection is not open.” 擷取階層的維度名時需要串連Cube才可以!
//dt.Columns.Add(new DataColumn(cs.Axes[1].Set.Hierarchies[col].ParentDimension.Name));
dt.Columns.Add(new DataColumn("Dimension" + col.ToString()));
}
int index = 0;
foreach (Position p in cs.Axes[0].Positions)
{
dc = new DataColumn();
string name = "";
foreach (Member m in p.Members)
{
name += m.Caption + "-";
}
if (name.Length > 0)
{
name = name.Substring(0, name.Length - 1);
}
//這裡防止維度成員或度量值重名而需要容錯處理
try
{
dc.ColumnName = name;
dt.Columns.Add(dc);
}
catch (System.Exception ex)
{
dc.ColumnName = name + index.ToString();
dt.Columns.Add(dc);
}
index++;
}
//添加行資料
int pos = 0;
foreach (Position py in cs.Axes[1].Positions)
{
dr = dt.NewRow();
//維度描述列資料
int cols = 0;
foreach (Member m in py.Members)
{
dr[cols] = m.Caption;
cols++;
}
//資料列
for (int x = 1; x <= cs.Axes[0].Positions.Count; x++)
{
dr[x + cols - 1] = cs[pos++].FormattedValue;
}
dt.Rows.Add(dr);
}
return dt;
} 四、改進後的結果 改進後就會得到圖三所示的DataTable,這樣我們就可以在程式中綁定資料了,四所示: