一、问题的提出
在利用MDX查询多维数据集的时候,经常会遇到这样一种情况,行轴或列轴含多个维度(CrossJoin),CellSet返回了多个维度成员的值,在将CellSet转成DataTable的时候,我们希望能返回这些维度成员的值。而利用网上搜索到的方法,如前文“FusionChart对MDX查询结果的数据展示案例”所述,是不能满足该功能的。
具体问题如下面图一和图二所示:
![](https://i-blog.csdnimg.cn/blog_migrate/2c86c634d854389159aa3760fbd88c49.jpeg)
图一 MDX查询时列轴有两个维度的CrossJoin
![](https://i-blog.csdnimg.cn/blog_migrate/39b84333229f6bb1f86adf9020be704d.jpeg)
图二 用之前的CellSet转DataTable方法后维度成员信息被拼在了一起
二、目标
我们希望得到图一所示的DataTable,即所有维度均作为列或者行返回。如下图三所示:
![](https://i-blog.csdnimg.cn/blog_migrate/48a2c0caa0c6f2055defda6e116b1a4a.jpeg)
图三 期待的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;
}
/// 将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,这样我们就可以在程序中绑定数据了,如图四所示:
![](https://i-blog.csdnimg.cn/blog_migrate/eb8a54b32b0914cb3cb1eb1c8837ae97.jpeg)