チュートリアル: C# と ADO.NET を使用して Azure SQL Database 内でリレーショナル データベースを設計する

適用対象:Azure SQL Database

Azure SQL データベースは、Microsoft Cloud (Azure) のリレーショナルなサービスとしてのデータベース (DBaaS) です。 このチュートリアルでは、Azure Portal、ADO.NET、および Visual Studio を使用して以下の手順を実行する方法を説明します。

  • Azure portal を使用してデータベースを作成する
  • Azure portal を使用してサーバーレベルの IP ファイアウォール規則を設定する
  • ADO.NET と Visual Studio を使用してデータベースに接続する
  • ADO.NET を使用してテーブルを作成する
  • ADO.NET を使用してデータを挿入、更新、削除する
  • ADO.NET を使用してデータのクエリを実行する

ヒント

この無料の Learn モジュールでは、単純なデータベースの作成など、Azure SQL Database に対してクエリを行う ASP.NET アプリケーションを開発および構成する方法を学習できます。

前提条件

Azure portal にサインインする

Azure portal にサインインします。

サーバーレベルの IP ファイアウォール規則を作成する

SQL Database では、サーバーレベルで IP ファイアウォールが作成されます。 このファイアウォールにより、外部のアプリケーションやツールは、ファイアウォール規則でその IP がファイアウォールの通過を許可されていない限り、サーバーおよびサーバー上のすべてのデータベースに接続できなくなります。 データベースに外部から接続できるようにするには、まず、IP アドレス (または IP アドレス範囲) に対する IP ファイアウォール規則を追加する必要があります。 以下の手順に従って、サーバーレベルの IP ファイアウォール規則を作成します。

重要

SQL Database の通信は、ポート 1433 上で行われます。 企業ネットワーク内からこのサービスに接続しようとしても、ポート 1433 でのアウトバウンド トラフィックがネットワークのファイアウォールで禁止されている場合があります。 その場合、管理者がポート 1433 を開かない限り、データベースに接続することはできません。

  1. デプロイが完了したら、左側のメニューから [SQL データベース] を選び、[SQL データベース] ページで "自分のデータベース" を選びます。 お客様のデータベースの概要ページが開くと、完全修飾サーバー名 (yourserver.database.windows.net など) や追加の構成オプションが表示されます。

  2. この完全修飾サーバー名をコピーします。これは、SQL Server Management Studio からお客様のサーバーとデータベースに接続するために使用します。

    Screenshot of the Azure portal, database overview page, with the server name highlighted.

  3. [設定] で、 [ネットワーク] を選択します。 [パブリック アクセス] タブを選択し、[パブリック ネットワーク アクセス][選択したネットワーク] を選択して、[ファイアウォール規則] セクションを表示します。

    Screenshot of the Azure portal, networking page, showing where to set the server-level IP firewall rule.

  4. ツール バーの [クライアント IP の追加] を選び、現在の IP アドレスを新しい IP ファイアウォール規則に追加します。 IP ファイアウォール規則は、単一の IP アドレスまたは IP アドレスの範囲に対して、ポート 1433 を開くことができます。

  5. [保存] を選択します。 サーバーでポート 1433 を開いている現在の IP アドレスに対して、サーバーレベルの IP ファイアウォール規則が作成されます。

  6. [OK] を選択し、 [ファイアウォール設定] ページを閉じます。

これで IP アドレスが IP ファイアウォールを通過できるようになりました。 SQL Server Management Studio やその他の任意のツールを使用して、データベースに接続できます。 必ず、お客様が先ほど作成したサーバー管理者アカウントを使用してください。

重要

既定では、すべての Azure サービスで、SQL Database IP ファイアウォール経由のアクセスが有効になります。 すべての Azure サービスに対するアクセスを無効にするには、このページの [オフ] を選びます。

C# プログラムの例

この記事の以降のセクションでは、ADO.NET を使って SQL Database に Transact-SQL (T-SQL) ステートメントを送る C# プログラムを紹介します。 C# プログラムは、以下の操作を行います。

エンティティ関係図 (ERD: Entity Relationship Diagram)

CREATE TABLE ステートメントでは、2 つのテーブルの間に "外部キー" (FK) リレーションシップを作成するために REFERENCES キーワードが使われています。 tempdb を使用している場合は、先頭に二重ダッシュを付けて --REFERENCES キーワードをコメントアウトしてください。

ERD は、2 つのテーブルのリレーションシップを示しています。 tabEmployee.DepartmentCode 列 ("") の値は、tabDepartment.DepartmentCode 列 ("") の値に限定されています。

ERD showing foreign key

Note

T-SQL を編集してテーブル名の前に # を追加すると、それらのテーブルが tempdb の一時テーブルになります。 この方法は、デモンストレーション用途で、利用できるテスト データベースがないときに便利です。 外部キーへの参照は使用中には強制されず、一時テーブルはプログラムの実行終了後に接続が閉じると自動的に削除されます。

コンパイルして実行するには

C# プログラムは論理的には 1 つの .cs ファイルですが、物理的にはいくつかのコード ブロックに分割されています。そうすることによって、各ブロックが理解しやすくなっています。 プログラムをコンパイルして実行するには、次の手順に従います。

  1. Visual Studio で C# プロジェクトを作成します。 プロジェクトの種類は、"コンソール" にします。これは、 [テンプレート]>[Visual C#]>[Windows デスクトップ]>[コンソール アプリ (.NET Framework)] にあります。

  2. Program.cs ファイルで、ひな形となるコード行を以下の手順で置き換えます。

    1. 以下のコード ブロックを、示されている順序でコピーして貼り付けます。データベースへの接続T-SQL の生成、およびデータベースへの送信に関するセクションを参照してください。

    2. Main メソッドで、以下の値を変更します。

      • cb.DataSource
      • cb.UserID
      • cb.Password
      • cb.InitialCatalog
  3. System.Data.dll アセンブリが参照されていることを確認します。 [ソリューション エクスプローラー] ウィンドウで [参照] ノードを展開して確認してください。

  4. Visual Studio でプログラムをビルドおよび実行するには、 [開始] ボタンを選択します。 レポート出力がプログラム ウィンドウに表示されますが、テストの実行ごとに GUID 値は異なります。

    =================================
    T-SQL to 2 - Create-Tables...
    -1 = rows affected.
    
    =================================
    T-SQL to 3 - Inserts...
    8 = rows affected.
    
    =================================
    T-SQL to 4 - Update-Join...
    2 = rows affected.
    
    =================================
    T-SQL to 5 - Delete-Join...
    2 = rows affected.
    
    =================================
    Now, SelectEmployees (6)...
    8ddeb8f5-9584-4afe-b7ef-d6bdca02bd35 , Alison , 20 , acct , Accounting
    9ce11981-e674-42f7-928b-6cc004079b03 , Barbara , 17 , hres , Human Resources
    315f5230-ec94-4edd-9b1c-dd45fbb61ee7 , Carol , 22 , acct , Accounting
    fcf4840a-8be3-43f7-a319-52304bf0f48d , Elle , 15 , NULL , NULL
    View the report output here, then press any key to end the program...
    

ADO.NET を使用して SQL Database に接続する

using System;
using System.Data.SqlClient;   // System.Data.dll
//using System.Data;           // For:  SqlDbType , ParameterDirection

namespace csharp_db_test
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                var cb = new SqlConnectionStringBuilder();
                cb.DataSource = "your_server.database.windows.net";
                cb.UserID = "your_user";
                cb.Password = "your_password";
                cb.InitialCatalog = "your_database";

                using (var connection = new SqlConnection(cb.ConnectionString))
                {
                    connection.Open();

                    Submit_Tsql_NonQuery(connection, "2 - Create-Tables", Build_2_Tsql_CreateTables());

                    Submit_Tsql_NonQuery(connection, "3 - Inserts", Build_3_Tsql_Inserts());

                    Submit_Tsql_NonQuery(connection, "4 - Update-Join", Build_4_Tsql_UpdateJoin(),
                        "@csharpParmDepartmentName", "Accounting");

                    Submit_Tsql_NonQuery(connection, "5 - Delete-Join", Build_5_Tsql_DeleteJoin(),
                        "@csharpParmDepartmentName", "Legal");

                    Submit_6_Tsql_SelectEmployees(connection);
                }
            }
            catch (SqlException e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("View the report output here, then press any key to end the program...");
            Console.ReadKey();
        }

T-SQL ステートメントを返すメソッド

static string Build_2_Tsql_CreateTables()
{
    return @"
        DROP TABLE IF EXISTS tabEmployee;
        DROP TABLE IF EXISTS tabDepartment;  -- Drop parent table last.

        CREATE TABLE tabDepartment
        (
            DepartmentCode  nchar(4)          not null    PRIMARY KEY,
            DepartmentName  nvarchar(128)     not null
        );

        CREATE TABLE tabEmployee
        (
            EmployeeGuid    uniqueIdentifier  not null  default NewId()    PRIMARY KEY,
            EmployeeName    nvarchar(128)     not null,
            EmployeeLevel   int               not null,
            DepartmentCode  nchar(4)              null
            REFERENCES tabDepartment (DepartmentCode)  -- (REFERENCES would be disallowed on temporary tables.)
        );
    ";
}

static string Build_3_Tsql_Inserts()
{
    return @"
        -- The company has these departments.
        INSERT INTO tabDepartment (DepartmentCode, DepartmentName)
        VALUES
            ('acct', 'Accounting'),
            ('hres', 'Human Resources'),
            ('legl', 'Legal');

        -- The company has these employees, each in one department.
        INSERT INTO tabEmployee (EmployeeName, EmployeeLevel, DepartmentCode)
        VALUES
            ('Alison'  , 19, 'acct'),
            ('Barbara' , 17, 'hres'),
            ('Carol'   , 21, 'acct'),
            ('Deborah' , 24, 'legl'),
            ('Elle'    , 15, null);
    ";
}

static string Build_4_Tsql_UpdateJoin()
{
    return @"
        DECLARE @DName1  nvarchar(128) = @csharpParmDepartmentName;  --'Accounting';

        -- Promote everyone in one department (see @parm...).
        UPDATE empl
        SET
            empl.EmployeeLevel += 1
        FROM
            tabEmployee   as empl
        INNER JOIN
            tabDepartment as dept ON dept.DepartmentCode = empl.DepartmentCode
        WHERE
            dept.DepartmentName = @DName1;
    ";
}

static string Build_5_Tsql_DeleteJoin()
{
    return @"
        DECLARE @DName2  nvarchar(128);
        SET @DName2 = @csharpParmDepartmentName;  --'Legal';

        -- Right size the Legal department.
        DELETE empl
        FROM
            tabEmployee   as empl
        INNER JOIN
            tabDepartment as dept ON dept.DepartmentCode = empl.DepartmentCode
        WHERE
            dept.DepartmentName = @DName2

        -- Disband the Legal department.
        DELETE tabDepartment
            WHERE DepartmentName = @DName2;
    ";
}

static string Build_6_Tsql_SelectEmployees()
{
    return @"
        -- Look at all the final Employees.
        SELECT
            empl.EmployeeGuid,
            empl.EmployeeName,
            empl.EmployeeLevel,
            empl.DepartmentCode,
            dept.DepartmentName
        FROM
            tabEmployee   as empl
        LEFT OUTER JOIN
            tabDepartment as dept ON dept.DepartmentCode = empl.DepartmentCode
        ORDER BY
            EmployeeName;
    ";
}

データベースに T-SQL を送信する

static void Submit_6_Tsql_SelectEmployees(SqlConnection connection)
{
    Console.WriteLine();
    Console.WriteLine("=================================");
    Console.WriteLine("Now, SelectEmployees (6)...");

    string tsql = Build_6_Tsql_SelectEmployees();

    using (var command = new SqlCommand(tsql, connection))
    {
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                Console.WriteLine("{0} , {1} , {2} , {3} , {4}",
                    reader.GetGuid(0),
                    reader.GetString(1),
                    reader.GetInt32(2),
                    (reader.IsDBNull(3)) ? "NULL" : reader.GetString(3),
                    (reader.IsDBNull(4)) ? "NULL" : reader.GetString(4));
            }
        }
    }
}

static void Submit_Tsql_NonQuery(
    SqlConnection connection,
    string tsqlPurpose,
    string tsqlSourceCode,
    string parameterName = null,
    string parameterValue = null
    )
{
    Console.WriteLine();
    Console.WriteLine("=================================");
    Console.WriteLine("T-SQL to {0}...", tsqlPurpose);

    using (var command = new SqlCommand(tsqlSourceCode, connection))
    {
        if (parameterName != null)
        {
            command.Parameters.AddWithValue(  // Or, use SqlParameter class.
                parameterName,
                parameterValue);
        }
        int rowsAffected = command.ExecuteNonQuery();
        Console.WriteLine(rowsAffected + " = rows affected.");
    }
}
} // EndOfClass
}

ヒント

SQL クエリの作成の詳細については、「チュートリアル: Transact-SQL ステートメントの作成」にアクセスしてください。

次のステップ

次のチュートリアルに進み、データ移行について確認してください。