チュートリアル: エンティティ クラスの挿入、更新、および削除の動作のカスタマイズ

Note

データセットと関連クラスは、アプリケーションがデータベースから切断されている間にアプリケーションがメモリ内のデータを操作できるようにする、2000 年代初期からのレガシ .NET Framework テクノロジです。 これらが特に役立つのは、ユーザーがデータを変更し、変更をデータベースに戻して保持できるようにするアプリケーションです。 データセットは非常に優れたテクノロジであることが証明されていますが、新しい .NET アプリケーションでは Entity Framework Core を使用することをお勧めしています。 Entity Framework には、オブジェクト モデルとして表形式データを操作する、より自然な方法が用意されており、よりシンプルなプログラミング インターフェイスが備わっています。

Visual Studio の LINQ to SQL ツールには、データベース内のオブジェクトに基づいて LINQ to SQL クラス (エンティティ クラス) を作成および編集するためのビジュアル デザイン サーフェイスが用意されています。 LINQ to SQL を使用すると、LINQ テクノロジを使用して SQL データベースにアクセスできます。 詳細については、「LINQ (統合言語クエリ)」を参照してください。

既定では、更新を実行するロジックは LINQ to SQL ランタイムによって提供されます。 ランタイムは、テーブルのスキーマ (列定義と主キー情報) に基づいて、既定の InsertUpdate、および Delete の各ステートメントを作成します。 既定の動作を使用しない場合は、更新動作を構成し、データベースのデータの操作に必要な挿入、更新および削除を実行する特定のストアド プロシージャを指定できます。 この方法は、既定の動作が生成されていない場合、たとえばエンティティ クラスがビューにマップされている場合にも実行できます。 また、データベースのテーブルへのアクセスには常にストアド プロシージャを通すようにすると、既定の更新動作をオーバーライドできます。 詳しくは、「ストアド プロシージャによる操作のカスタマイズ」をご覧ください。

注意

このチュートリアルでは、Northwind データベースで InsertCustomerUpdateCustomer、および DeleteCustomer の各ストアド プロシージャを使用できるようにしておく必要があります。

このチュートリアルでは、ストアド プロシージャを使用して、データベースにデータを保存する既定の LINQ to SQL ランタイムの動作をオーバーライドするために必要な手順を示します。

このチュートリアルでは、次のタスクを実行する方法を学習します。

  • 新しい Windows フォーム アプリケーションを作成し、LINQ to SQL ファイルを追加します。

  • Northwind の Customers テーブルにマップされるエンティティ クラスを作成します。

  • LINQ to SQL Customer クラスを参照するオブジェクト データ ソースを作成します。

  • Customer クラスにバインドされる DataGridView を含む Windows フォームを作成します。

  • フォームの保存機能を実装します。

  • O/R デザイナーにストアド プロシージャを追加することにより、DataContext のメソッドを作成します。

  • ストアド プロシージャを使用して挿入、更新、および削除を実行するように Customer クラスを構成します。

必須コンポーネント

このチュートリアルでは SQL Server Express LocalDB と Northwind サンプル データベースを使用します。

  1. SQL Server Express LocalDB がない場合は、SQL Server Express のダウンロード ページからインストールするか、Visual Studio インストーラーを使用してインストールします。 Visual Studio インストーラーでは、データ ストレージとデータ処理ワークロードの一部として、または個別のコンポーネントとして、SQL Server Express LocalDB をインストールできます。

  2. 次の手順に従って、Northwind サンプル データベースをインストールします。

    1. Visual Studio で、 [SQL Server オブジェクト エクスプローラー] ウィンドウを開きます。 (SQL Server オブジェクト エクスプローラーは、Visual Studio インストーラーデータ ストレージとデータ処理ワークロードの一部としてインストールされます)。 [SQL Server] ノードを展開します。 LocalDB インスタンスを右クリックし、 [新しいクエリ] を選択します。

      クエリ エディター ウィンドウが開きます。

    2. Northwind Transact-SQL スクリプトをクリップボードにコピーします。 この T-SQL スクリプトを使用すると、Northwind データベースが新規作成され、データが設定されます。

    3. T-SQL スクリプトをクエリ エディターに貼り付け、 [実行] ボタンを選択します。

      しばらくすると、クエリの実行が完了し、Northwind データベースが作成されます。

アプリケーションの作成と LINQ to SQL クラスの追加

LINQ to SQL クラスを操作してデータを Windows フォームに表示できるように、新しい Windows フォーム アプリケーションを作成し、LINQ to SQL クラス ファイルを追加します。

Note

この記事で紹介する Visual Studio ユーザー インターフェイス要素の一部は、お使いのコンピューターでは名前や場所が異なる場合があります。 Visual Studio のエディションや環境設定がお使いのものと異なる場合があります。 詳細については、「Visual Studio IDE のカスタマイズ」を参照してください。

LINQ to SQL クラスを含む新しい Windows フォーム アプリケーション プロジェクトを作成するには

  1. Visual Studio の [ファイル] メニューで、 [新規作成]>[プロジェクト] を選択します。

  2. 左側のペインで [Visual C#] または [Visual Basic] を展開し、 [Windows デスクトップ] を選択します。

  3. 中央のペインで、 [Windows フォーム アプリ] プロジェクト タイプを選択します。

  4. プロジェクトに UpdatingWithSProcsWalkthrough という名前を付け、 [OK] を選択します。

    UpdatingWithSProcsWalkthrough プロジェクトが作成されて、ソリューション エクスプローラーに追加されます。

  5. [プロジェクト] メニューの [新しい項目の追加] をクリックします。

  6. [LINQ to SQL クラス] テンプレートをクリックし、[名前] ボックスに「Northwind.dbml」と入力します。

  7. [追加] をクリックします。

    プロジェクトに空の LINQ to SQL クラス ファイル (Northwind.dbml) が追加され、O/R デザイナーが開きます。

Customer エンティティ クラスとオブジェクト データ ソースの作成

サーバー エクスプローラーまたはデータベース エクスプローラーから O/R デザイナーにテーブルをドラッグして、データベース テーブルにマップされた LINQ to SQL クラスを作成します。 結果は、データベース内のテーブルにマップされた LINQ to SQL エンティティ クラスになります。 作成したエンティティ クラスは、パブリック プロパティを持つ他のクラスと同様に、オブジェクト データ ソースとして使用できます。

Customer エンティティ クラスを作成し、そのエンティティ クラスでデータ ソースを構成するには

  1. サーバー エクスプローラーまたはデータベース エクスプローラーで、SQL Server バージョンの Northwind サンプル データベース上の Customer テーブルを探します。

  2. サーバー エクスプローラーまたはデータベース エクスプローラーから *O/R デザイナー サーフェイスに [Customers] ノードをドラッグします。

    Customer という名前のエンティティ クラスが作成されます。 これには、Customers テーブルの列に対応するプロパティが含まれています。 このエンティティ クラスは Customers テーブルの 1 人の顧客を表すため、Customers ではなく Customer という名前が付けられます。

    Note

    このような名前の変更動作を複数形化と呼びます。 これは [オプション] ダイアログ ボックスでオンまたはオフにできます。 詳細については、「方法: 複数形化をオンおよびオフにする (O-R デザイナー)」を参照してください。

  3. [ビルド] メニューの [UpdatingwithSProcsWalkthrough のビルド] をクリックして、プロジェクトをビルドします。

  4. [データ ソース] ウィンドウを開くには、 [データ] メニューの [データ ソースの表示] をクリックします。

  5. [データ ソース] ウィンドウで、 [新しいデータ ソースの追加]をクリックします。

  6. [データソースの種類を選択] ページで、[オブジェクト] をクリックし、[次へ] をクリックします。

  7. [UpdatingwithSProcsWalkthrough] ノードを展開し、[Customer] クラスを探して選択します。

    Note

    Customer クラスが使用可能でない場合は、ウィザードをキャンセルし、プロジェクトをビルドしてからウィザードを再実行します。

  8. [完了] をクリックしてデータ ソースを作成し、Customer エンティティ クラスを [データ ソース] ウィンドウに追加します。

Windows フォームに顧客データを表示するための DataGridView の作成

[データ ソース] ウィンドウから Windows フォームに LINQ to SQL のデータ ソース項目をドラッグして、エンティティ クラスにバインドされるコントロールを作成します。

エンティティ クラスにバインドされるコントロールを追加するには

  1. デザイン ビューで [Form1] を開きます。

  2. [データ ソース] ウィンドウから [Form1][Customer] ノードをドラッグします。

    Note

    [データ ソース] ウィンドウを表示するには、[データ] メニューの [データ ソースの表示] をクリックします。

  3. コード エディターで [Form1] を開きます。

  4. フォームに次のコードを追加します。フォームに対してグローバルになるように、Form1 クラスの内部でありながら、どのメソッドにも属さない位置に追加します。

    private NorthwindDataContext northwindDataContext1
        = new NorthwindDataContext();
    
  5. Form_Load イベントのイベント ハンドラーを作成し、ハンドラーに次のコードを追加します。

    customerBindingSource.DataSource
        = northwindDataContext1.Customers;
    

保存機能を実装する

既定では、保存ボタンが有効ではなく、保存機能は実装されていません。 また、オブジェクト データ ソースに対してデータ バインド コントロールを作成しても、変更されたデータをデータベースに保存するコードは自動的には追加されません。 ここでは、保存ボタンを有効にし、LINQ to SQL オブジェクトの保存機能を実装する方法について説明します。

保存機能を実装するには

  1. デザイン ビューで [Form1] を開きます。

  2. CustomerBindingNavigator の保存ボタン (フロッピー ディスクのアイコンのボタン) を選択します。

  3. [プロパティ] ウィンドウで、[Enabled] プロパティを [True] に設定します。

  4. 保存ボタンをダブルクリックして、イベント ハンドラーを作成し、コード エディターに切り替えます。

  5. 保存ボタンのイベント ハンドラーに次のコードを追加します。

    northwindDataContext1.SubmitChanges();
    

更新 (Insert、Update、および Delete) の実行に対する既定の動作のオーバーライド

既定の更新動作をオーバーライドするには

  1. O/R デザイナーで LINQ to SQL ファイルを開きます。 (ソリューション エクスプローラーNorthwind.dbml ファイルをダブルクリックします。)

  2. サーバー エクスプローラーまたはデータベース エクスプローラーで、Northwind データベースの [ストアド プロシージャ] ノードを展開し、InsertCustomersUpdateCustomers、および DeleteCustomers の各ストアド プロシージャを探します。

  3. 3 つのストアド プロシージャをすべて O/R デザイナーにドラッグします。

    各ストアド プロシージャが DataContext のメソッドとしてメソッド ペインに追加されます。 詳細については、「DataContext メソッド (O/R デザイナー)」を参照してください。

  4. O/R デザイナー[Customer] エンティティ クラスを選択します。

  5. [プロパティ] ウィンドウで [Insert] プロパティを選択します。

  6. [ランタイムを使用] の横にある省略記号 ([...]) をクリックして、[動作の構成] ダイアログ ボックスを開きます。

  7. [カスタマイズ] を選択します。

  8. [カスタマイズ] リストの [InsertCustomers] メソッドを選択します。

  9. [適用] をクリックして、選択したクラスと動作の構成を保存します。

    Note

    変更を行うたびに [適用] をクリックすると、各クラスと動作の組み合わせに対して動作の構成を続けることができます。 [適用] をクリックする前にクラスまたは動作を変更した場合は、警告ダイアログ ボックスが表示され、ここで変更を適用できます。

  10. [動作] リストの [Update] を選択します。

  11. [カスタマイズ] を選択します。

  12. [カスタマイズ] リストの [UpdateCustomers] メソッドを選択します。

    [メソッドの引数] および [クラスのプロパティ] のリストを調べると、テーブルの一部の列には 2 つのメソッドの引数と 2 つのクラスのプロパティがあることがわかります。 これにより、変更を追跡したり、コンカレンシー違反をチェックするステートメントを作成したりすることが簡単になります。

  13. Original_CustomerID メソッド引数を CustomerID (オリジナル) クラス プロパティにマップします。

    Note

    既定では、メソッド引数は名前が一致した場合にクラス プロパティにマップされます。 プロパティ名が変更され、テーブルとエンティティ クラス間で一致しなくなったために、O/R デザイナーが正しいマッピングを判断できないときは、マップ先となる同等のクラス プロパティを選択することが必要になる場合があります。 また、メソッド引数のマップ先として有効なクラス プロパティがない場合は、[クラスのプロパティ] 値を [(なし)] に設定できます。

  14. [適用] をクリックして、選択したクラスと動作の構成を保存します。

  15. [動作] リストの [Delete] を選択します。

  16. [カスタマイズ] を選択します。

  17. [カスタマイズ] リストの [DeleteCustomers] メソッドを選択します。

  18. Original_CustomerID メソッド引数を CustomerID (オリジナル) クラス プロパティにマップします。

  19. [OK] をクリックします。

Note

この特定のチュートリアルに限った問題ではありませんが、LINQ to SQL は、ID 列 (自動インクリメント)、rowguidcol 列 (データベースが生成したグローバル一意識別子 (GUID))、およびタイムスタンプ列であれば、データベースによって生成された値を、挿入時および更新時に自動的に処理します。 その他の列型のデータベースが生成した値は、予想に反して null 値になります。 データベースが生成した値を返すには、手動で IsDbGeneratedtrue に設定し、AutoSyncAutoSync.AlwaysAutoSync.OnInsert、または AutoSync.OnUpdate のいずれかに設定する必要があります。

アプリケーションをテストする

アプリケーションを再実行し、データベース内の顧客レコードが UpdateCustomers ストアド プロシージャによって正しく更新されることを確認します。

  1. F5キーを押します。

  2. グリッド内のレコードを変更して、更新動作をテストします。

  3. 新しいレコードを追加して、挿入動作をテストします。

  4. 保存ボタンをクリックして変更をデータベースに保存します。

  5. フォームを閉じます

  6. F5 キーを押し、更新されたレコードと新しく挿入したレコードが永続化されていることを確認します。

  7. 手順 3 で作成した新しいレコードを削除して、削除動作をテストします。

  8. 保存ボタンをクリックして変更を送信し、削除されたレコードをデータベースから削除します。

  9. フォームを閉じます

  10. F5 キーを押し、削除したレコードがデータベースから削除されていることを確認します。

    Note

    アプリケーションで SQL Server Express Edition を使用している場合、データベース ファイルの [出力ディレクトリにコピー] プロパティの値によっては、手順 10 で F5 キーを押したときに変更が表示されない場合があります。

次のステップ

アプリケーションの要件に応じて、LINQ to SQL エンティティ クラスの作成後にいくつかの手順を実行することが必要な場合があります。 このアプリケーションで行うことができる拡張には次のものがあります。