セルセットを使用したデータの取得

分析データを取得する際、対話性と柔軟性に最も優れている方法が CellSet オブジェクトです。CellSet オブジェクトは階層データおよびメタデータのインメモリ キャッシュであり、これらのデータの元の次元を保持します。CellSet オブジェクトは、接続された状態でも、接続されていない状態でもスキャンすることができます。非接続状態でもアクセス可能なことから、CellSet オブジェクトを使用すれば、データやメタデータを任意の順序で表示できます。つまり、CellSet は、データ取得の最も包括的なオブジェクト モデルといえます。一方で、CellSet オブジェクトはオーバーヘッドが非常に大きく、最も低速な ADOMD.NET データ取得オブジェクト モデルでもあります。

接続状態でのデータの取得

CellSet オブジェクトを使用してデータを取得するには、次の手順を実行します。

  1. このオブジェクトの新しいインスタンスを作成します。

    CellSet オブジェクトの新しいインスタンスを作成するには、AdomdCommand オブジェクトの Execute または ExecuteCellSet メソッドを呼び出します。

  2. メタデータを確認します。

    データを取得する以外に、ADOMD.NET はセルセットのメタデータも取得します。コマンドによってクエリが実行され、CellSet が返されるとすぐに、さまざまなオブジェクトを通じてメタデータを取得できるようになります。このメタデータは、クライアント アプリケーションがセルセット データを表示したり、セルセット データを操作したりする際に必要となります。たとえば、多くのクライアント アプリケーションには、セルセット内の指定した位置をドリル ダウンし、子の位置を階層的に表示するための機能が備わっています。

    ADOMD.NET では、CellSet オブジェクトの Axes プロパティおよび FilterAxis プロパティは、返されたセルセット内のクエリおよびスライサ軸のメタデータをそれぞれ表します。これら 2 つのプロパティは、Axis オブジェクトへの参照を返します。さらに、このオブジェクトには、各軸上での位置が含まれています。

    Axis オブジェクトは、その軸で使用可能な組のセットを表す Position オブジェクトのコレクションを格納します。各 Position オブジェクトは、1 つの組を表しています。この組は、Member オブジェクトのコレクションによって表される 1 つまたは複数のメンバを含みます。

  3. セルセット コレクションからデータを取得します。

    メタデータを取得する以外に、ADOMD.NET はセルセットのデータも取得します。コマンドによってクエリが実行され、CellSet が返されるとすぐに、CellSetCells コレクションを使用してデータを取得できるようになります。このコレクションには、クエリのすべての軸の交差部分について計算された値が含まれます。したがって、各交差部分 (セル) にアクセスするためのインデクサがいくつかあります。インデクサの一覧については、「Item」を参照してください。

接続状態でのデータの取得例

次の例では、ローカル サーバーへの接続を確立し、その接続に対してコマンドを実行します。この例では、CellSet オブジェクト モデルを使用して結果を解析します。列のキャプション (メタデータ) は最初の軸から取得され、各行のキャプション (メタデータ) は 2 つ目の軸から取得されます。また、交差部分のデータは、Cells コレクションを使用して取得されます。

string ReturnCommandUsingCellSet()
{
    //Create a new string builder to store the results
    System.Text.StringBuilder result = new System.Text.StringBuilder();

    //Connect to the local server
    using (AdomdConnection conn = new AdomdConnection("Data Source=localhost;"))
    {
        conn.Open();

        //Create a command, using this connection
        AdomdCommand cmd = conn.CreateCommand();
        cmd.CommandText = @"
                      WITH MEMBER [Measures].[FreightCostPerOrder] AS 
                            [Measures].[Reseller Freight Cost]/[Measures].[Reseller Order Quantity],  
                            FORMAT_STRING = 'Currency'
                      SELECT 
                            [Geography].[Geography].[Country].&[United States].Children ON ROWS, 
                            [Date].[Calendar].[Calendar Year] ON COLUMNS
                      FROM [Adventure Works]
                      WHERE [Measures].[FreightCostPerOrder]";

        //Execute the query, returning a cellset
        CellSet cs = cmd.ExecuteCellSet();

        //Output the column captions from the first axis
        //Note that this procedure assumes a single member exists per column.
        result.Append("\t");
        TupleCollection tuplesOnColumns = cs.Axes[0].Set.Tuples;
        foreach (Tuple column in tuplesOnColumns)
        {
            result.Append(column.Members[0].Caption + "\t");
        }
        result.AppendLine();

        //Output the row captions from the second axis and cell data
        //Note that this procedure assumes a two-dimensional cellset
        TupleCollection tuplesOnRows = cs.Axes[1].Set.Tuples;
        for (int row = 0; row < tuplesOnRows.Count; row++)
        {
            result.Append(tuplesOnRows[row].Members[0].Caption + "\t");
            for (int col = 0; col < tuplesOnColumns.Count; col++)
            {
                result.Append(cs.Cells[col, row].FormattedValue + "\t");
            }
            result.AppendLine();
        }
        conn.Close();

        return result.ToString();
    } // using connection
}

非接続状態でのデータの取得

前のクエリで返された XML を読み込むことにより、接続中でなくても、CellSet オブジェクトを使用して析データを包括的に参照することができます。

注意

CellSet オブジェクトからアクセスできるオブジェクトのプロパティの中には、非接続状態では使用できないものがあります。詳細については、「LoadXml」を参照してください。

非接続状態でのデータの取得例

次の例は、このトピックで前述したメタデータとデータの例に似ています。ただし、この例のコマンドは、ExecuteXmlReader への呼び出しを使用して実行され、結果は System.Xml.XmlReader として返されます。その後、LoadXml メソッドと共にこの System.Xml.XmlReader を使用して CellSet オブジェクトを設定します。この例では System.Xml.XmlReader をすぐに読み込みますが、データをセルセットに読み込む前に、リーダーからハード ディスクに格納された XML をキャッシュするか、なんらかの方法でデータを別のアプリケーションに転送することもできます。

string DemonstrateDisconnectedCellset()
{
    //Create a new string builder to store the results
    System.Text.StringBuilder result = new System.Text.StringBuilder();

    //Connect to the local server
    using (AdomdConnection conn = new AdomdConnection("Data Source=localhost;"))
    {
        conn.Open();

        //Create a command, using this connection
        AdomdCommand cmd = conn.CreateCommand();
        cmd.CommandText = @"
                      WITH MEMBER [Measures].[FreightCostPerOrder] AS 
                            [Measures].[Reseller Freight Cost]/[Measures].[Reseller Order Quantity],  
                            FORMAT_STRING = 'Currency'
                      SELECT 
                            [Geography].[Geography].[Country].&[United States].Children ON ROWS, 
                            [Date].[Calendar].[Calendar Year] ON COLUMNS
                      FROM [Adventure Works]
                      WHERE [Measures].[FreightCostPerOrder]";


        //Execute the query, returning an XmlReader
        System.Xml.XmlReader x = cmd.ExecuteXmlReader();

        //At this point, the XmlReader could be stored on disk,
        //transmitted, modified, cached, or otherwise manipulated

        //Load the CellSet with the specified XML
        CellSet cs = CellSet.LoadXml(x);

        //Now that the XmlReader has finished being read
        //we can close it and the connection, while the
        //CellSet can continue being used.
        x.Close();
        conn.Close();

        //Output the column captions from the first axis
        //Note that this procedure assumes a single member exists per column.
        result.Append("\t");
        TupleCollection tuplesOnColumns = cs.Axes[0].Set.Tuples;
        foreach (Tuple column in tuplesOnColumns)
        {
            result.Append(column.Members[0].Caption + "\t");
        }
        result.AppendLine();

        //Output the row captions from the second axis and cell data
        //Note that this procedure assumes a two-dimensional cellset
        TupleCollection tuplesOnRows = cs.Axes[1].Set.Tuples;
        for (int row = 0; row < tuplesOnRows.Count; row++)
        {
            result.Append(tuplesOnRows[row].Members[0].Caption + "\t");
            for (int col = 0; col < tuplesOnColumns.Count; col++)
            {
                result.Append(cs.Cells[col, row].FormattedValue + "\t");
            }
            result.AppendLine();
        }

        return result.ToString();
    } // using connection
}