次の方法で共有


チュートリアル: SQL Server 空間クエリによるマップ レポートの作成

SQL Server のクエリから空間データをマップ レポートに使用するには、3 つの主要な手順が含まれます。

  1. 空間データのクエリのためのデータ オブジェクトを作成する

  2. データ オブジェクトを使用してマップ レポートをデザインする

  3. ReportViewer コントロールへのクエリ データを提供する

このチュートリアルでは、Windows フォーム アプリケーション プロジェクトで SQL Server 空間クエリ オプションを使用して、初めてのマップ レポートを正しくデザインおよび表示するために必要なすべての手順を説明します。

重要な注意事項重要

Visual Studio のデータセット デザイナーは、SQL Server の空間型を返すクエリには使用できません。データセット デザイナーは、ユーザー定義型 (UDT) をサポートしていません。このカテゴリには、SQL Server の空間型 (SqlGeometry と SqlGeography) が属しています。

必要条件

空間データのクエリのためのデータ オブジェクトを作成する

  1. GAC から選択したディレクトリに Microsoft.SqlServer.Types.dll (Version 11.0.0.0) のコピーを作成します。そのためには、コマンド プロンプトで次のコマンドを実行します。

    Copy C:\Windows\assembly\GAC_MSIL\Microsoft.SqlServer.Types\11.0.0.0__89845dcd8080cc91\Microsoft.SqlServer.Types.dll <destination_folder>
    
    重要な注意事項重要

    既定では、C:\Windows\assembly の下のフォルダーは では表示されません。これらは、コマンド プロンプトでのみ表示されます。

  2. Visual Studio の [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。

  3. [新しいプロジェクト] ダイアログ ボックスで、[Windows フォーム アプリケーション] を選択し、「MapWithSqlQuery」という名前を付けて [OK] をクリックします。

  4. ソリューション エクスプローラーで、プロジェクトの [参照設定] ノードを右クリックし、[参照の追加] をクリックします。

  5. [参照] ボタンをクリックして Microsoft.SqlServer.Types.dll (Version 11.0.0.0) をコピーしたディレクトリに移動します。ファイルを選択して [開く] をクリックし、[追加] をクリックします。

    これで、データ オブジェクトで SqlGeometry および SqlGeography 型を使用できるようになりました。

  6. ソリューション エクスプローラーで、使用するプロジェクトを右クリックし、[追加] をポイントして、[クラス] を選択します。

  7. ファイルに「StoreSalesAndLocations.cs」という名前を付け、[追加] をクリックします。

  8. StoreSalesAndLocations.cs ファイルを開き、StoreSalesAndLocations のクラスの中かっこ内に次のパブリック プロパティを定義します。

    public double TotalDue { get; set; }
    public string Store { get; set; }
    public Microsoft.SqlServer.Types.SqlGeography SpatialLocation { get; set; }
    
  9. 次のコードをプロパティ定義の下にコピーし、データベース サーバーの名前の <DBServerName> パラメーターを変更します。

    // Returns the IEnumerable needed by the Report Designer to create a business object dataset.
    public static IEnumerable<StoreSalesAndLocations> ReadFromDatabase()
    {
        string connectionString = "Data Source=<DBServerName>;Initial Catalog=AdventureWorks2008R2;Integrated Security=True";
        using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
        {
            // The following query returns all sales orders from US physical stores, with the 
            // individual order total, store where the order is placed, and the store location.
            string queryText = @"
                SELECT soh.TotalDue, st.Name AS Store, ad.SpatialLocation
                FROM Sales.SalesOrderHeader AS soh INNER JOIN
                  Sales.Customer AS c ON soh.CustomerID = c.CustomerID INNER JOIN
                  Person.BusinessEntity AS b ON b.BusinessEntityID = c.StoreID INNER JOIN
                  Sales.Store AS st ON st.BusinessEntityID 
                     = b.BusinessEntityID INNER JOIN
                  Person.BusinessEntityAddress AS a 
                     ON a.BusinessEntityID = b.BusinessEntityID INNER JOIN
                  Person.Address AS ad ON ad.AddressID = a.AddressID INNER JOIN
                  Person.AddressType AS at ON at.AddressTypeID = a.AddressTypeID
                     INNER JOIN Person.StateProvince AS sp 
                     ON sp.StateProvinceID = ad.StateProvinceID
                WHERE (c.StoreID IS NOT NULL) 
                   AND (at.Name = N'Main Office') AND (sp.CountryRegionCode = N'US')
            ";
            var command = new System.Data.SqlClient.SqlCommand(queryText, connection);
            command.CommandType = System.Data.CommandType.Text;
            connection.Open();
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    var next = new StoreSalesAndLocations() 
                    {
                        TotalDue = Double.Parse(reader["TotalDue"].ToString()),
                        Store = reader["Store"].ToString(),
                        SpatialLocation = ReadSqlGeography(reader, "SpatialLocation")
                    };
    
                    yield return next;
                }
            }
        }
    }
    
    // Parses a geography column from a T-SQL query into the CLR SqlGeography type.
    private static Microsoft.SqlServer.Types.SqlGeography ReadSqlGeography(System.Data.SqlClient.SqlDataReader reader, string columnName)
    {
        var dataInBytes = reader.GetSqlBytes(reader.GetOrdinal(columnName));
        var newGeography = new Microsoft.SqlServer.Types.SqlGeography();
        using (var dataStream = dataInBytes.Stream)
        {
            newGeography.Read(new System.IO.BinaryReader(dataStream));
        }
        return newGeography;
    }
    
    重要な注意事項重要

    SQL Server の空間データを SqlGeometry または SqlGeography に変換する必要があるかどうかを確認するには、対象となる列のテーブル定義を調べます。列の型が geometry である場合は、SqlGeometry に変換する必要があります。列の型が geography である場合は、SqlGeography に変換する必要があります。

  10. ソリューションをビルドします。これにより、レポート デザイナーから起動された場合に、データ ソース構成ウィザードで新しいクラスを表示できるようになります。

次のセクションでは、作成したデータ オブジェクトを使用してマップ レポートを設計します。開始する前に、データ オブジェクトを使用して既にソリューションをビルドしてあることを確認します。その他の場合は、データ オブジェクトがデータ ソース構成ウィザードで後から表示されるようにならないため、レポートで使用できません。

データ オブジェクトを使用してマップ レポートをデザインする

  1. ソリューション エクスプローラーでプロジェクトを右クリックし、[追加] をポイントして、[新しいアイテム] をクリックします。

  2. [新しい項目の追加] ダイアログ ボックスで、[レポート] の項目型をクリックし、既定のファイル名を受け入れて [OK] をクリックします。レポートは、レポート デザイナーで自動的に開きます。

  3. 新しいマップ レイヤー ウィザードを起動するには、ツールボックスからデザイン サーフェイスにマップのレポート アイテムをドラッグします。

  4. [空間データのソースを選択] ページで、[SQL Server 空間クエリ] を選択し、[次へ] をクリックします。

  5. データ ソース構成ウィザードが自動的に起動されない場合は、[新規作成] をクリックして新しいデータ ソースを作成します。

  6. データ ソース構成ウィザードで、[オブジェクト] を選択して [次へ] をクリックします。

  7. ツリー ビューから新しいデータ クラスを下に示されているように選択し、[完了] をクリックして [データセットのプロパティ] ページで [次へ] をクリックします。

    レポートのデータセット: SQL クエリ データ オブジェクトを選択する

  8. [OK] をクリックしてポップアップ ダイアログを閉じます。

  9. [レイヤーの種類] ボックスで [ポイント] を選択します。また、[Bing Maps のレイヤーを追加する] を選択します。その後、[次へ] をクリックします。

  10. [マップの視覚エフェクトを選択] で [バブル マップ] を選択して [次へ] をクリックします。[データセットのプロパティ] ページは、バブル マップのデータを指定できるように再度開きます。

  11. [データ ソース] の一覧で、[MapWithSqlQuery] を選択して [次へ] をクリックし、[次へ] をもう一度クリックします。

    ヒントヒント

    ここでは、ウィザードによってレポート内の 2 番目のデータセットを作成します。使用するデータセットは既に空間データと解析データを含むため、厳密に言えば 2 種類のデータセットは必要ではありません。ただし、簡単にするために両方のデータセット、「DataSet1」および「DataSet2」を保持します。

  12. [配色テーマとデータの視覚エフェクトを選択] では、[バブルのサイズを使用してデータを表示する] が選択され、[データ フィールド] の一覧から [Sum(TotalDue)] が選択されていることを確認します。この手順は各ストアの販売合計に従ってバブル サイズを示すためにバブル マップを構成します。

  13. [完了] をクリックします。

    重要な注意事項重要

    「使用できる空間データがありません。サンプル空間データがマップに表示されます。」というメッセージが表示される場合があります。これは、オブジェクト データ ソースを使用していて、デザイン時に使用できるデータがないためです。これは、次のことを意味します。

    • 実行時に、マップのビュー ポートは、データセットのデータ ポイントに合わせて中心とズームが実行されます。

    • デザイン時には、マップのビュー ポートは実行時に示される実際の中心とズームを示すことはできません。

    • 前述のデザイン時の制限によって、デザイン時のマップの中心とズームをカスタマイズすることは非常に困難です。

セクション内で、レポートで定義されている 2 つのデータセット (「DataSet1」および「DataSet2」) のクエリ データに ReportViewer がアクセスできることを確認します。これらは実際には同じデータセットであるため、データを一度取得し、データセット名の両方の LocalReportDataSources プロパティに追加するだけで済みます。

ReportViewer コントロールへのクエリ データを提供する

  1. ソリューション エクスプローラーで、フォーム デザイナーの Form1.cs ファイルを開きます。[ツールボックス][レポート] カテゴリで、ReportViewer コントロールをフォームにドラッグします。

  2. ReportViewer タスクのスマート タグで、作成したレポートを選択し、[親コンテナーにドッキングする] を選択します。

  3. ソリューション エクスプローラーで、[Form1.cs] を右クリックし、[コードの表示] を選択してコード エディターで開きます。

  4. Form1_Load() メソッドの RefreshReport() 呼び出しの前に、次のコードをコピーして追加します。

    IEnumerable<StoreSalesAndLocations> reportData = StoreSalesAndLocations.ReadFromDatabase();
    reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", reportData));
    reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet2", reportData));
    
  5. プロジェクトを実行するには、[デバッグ] メニューの [デバッグ開始] を選択します。

関連項目

タスク

チュートリアル : ローカル処理モードでのビジネス オブジェクト データ ソースと ReportViewer Windows フォーム コントロールの使用

その他の技術情報

サンプルとチュートリアル