ASP.NET Web ページ (Razor) サイトでのデータベースの操作の概要

Tom FitzMacken

この記事では、Microsoft WebMatrix ツールを使用して、ASP.NET Web ページ (Razor) Web サイトにデータベースを作成する方法と、データを表示、追加、編集、削除できるページを作成する方法について説明します。

学習内容:

  • データベースを作成する方法。
  • データベースに接続する方法。
  • Web ページにデータを表示する方法。
  • データベース レコードを挿入、更新、削除する方法。

記事で紹介されている機能は次のとおりです。

  • Microsoft SQL Server Compact Edition データベースの操作。
  • SQL クエリの操作。
  • Database クラスです。

チュートリアルで使用するソフトウェアのバージョン

  • ASP.NET Web ページ (Razor) 2
  • WebMatrix 2

このチュートリアルは、WebMatrix 3 でも動作します。 ASP.NET Web ページ 3 と Visual Studio 2013 (または Web の場合は Visual Studio Express 2013) を使用できますが、ユーザー インターフェイスは異なります。

データベースの概要

一般的なアドレス帳を想像してみてください。 アドレス帳の各エントリ (つまり、各ユーザー) には、名、姓、住所、電子メール アドレス、電話番号など、いくつかの情報があります。

このようなデータを画像化する一般的な方法は、行と列を含むテーブルです。 データベース用語では、各行はレコードと呼ばれることがよくあります。 各列 (フィールドとも呼ばれます) には、データの種類 (名、姓など) ごとに値が含まれます。

ID FirstName LastName アドレス Email 電話
1 Jim Abrus 210 100th St SE Orcas WA 98031 jim@contoso.com 555 0100
2 Terry Adams 1234 メイン セント シアトル WA 99011 terry@cohowinery.com 555 0101

ほとんどのデータベース テーブルでは、テーブルに、顧客番号、アカウント番号などの一意の識別子を含む列が必要です。これはテーブルの 主キーと呼ばれ、テーブル内の各行を識別するために使用します。 この例では、ID 列がアドレス帳の主キーです。

このデータベースの基本的な理解により、単純なデータベースを作成し、データの追加、変更、削除などの操作を実行する方法を学習できます。

ヒント

リレーショナル データベース

テキスト ファイルやスプレッドシートなど、さまざまな方法でデータを格納できます。 ただし、ほとんどのビジネス用途では、データはリレーショナル データベースに格納されます。

この記事では、データベースについて詳しく説明しません。 ただし、それらについて少し理解すると役に立つ場合があります。 リレーショナル データベースでは、情報は論理的に別々のテーブルに分割されます。 たとえば、学校のデータベースには、学生とクラスオファリング用の個別のテーブルが含まれている場合があります。 データベース ソフトウェア (SQL Server など) では、テーブル間のリレーションシップを動的に確立できる強力なコマンドがサポートされています。 たとえば、リレーショナル データベースを使用して、スケジュールを作成するために学生とクラスの間に論理的な関係を確立できます。 データを別のテーブルに格納すると、テーブル構造の複雑さが軽減され、テーブルに冗長なデータを保持する必要が減ります。

データベースの作成

この手順では、WebMatrix に含まれている SQL Server Compact Database デザイン ツールを使用して SmallBakery という名前のデータベースを作成する方法を示します。 コードを使用してデータベースを作成できますが、WebMatrix などのデザイン ツールを使用してデータベーステーブルとデータベース テーブルを作成する方が一般的です。

  1. WebMatrix を起動し、[クイック スタート] ページで [ テンプレートからサイト] をクリックします。

  2. [ 空のサイト] を選択し、[ サイト名 ] ボックスに「SmallBakery」と入力し、[OK] をクリック します。 サイトが作成され、WebMatrix に表示されます。

  3. 左側のウィンドウで、[ データベース ] ワークスペースをクリックします。

  4. リボンの [ 新しいデータベース] をクリックします。 空のデータベースは、サイトと同じ名前で作成されます。

  5. 左側のウィンドウで、 SmallBakery.sdf ノードを展開し、[ テーブル] をクリックします。

  6. リボンの [ 新しいテーブル] をクリックします。 WebMatrix によってテーブル デザイナーが開きます。

    [テーブル デザイナーを開く Web マトリックスを示すスクリーンショット。]

  7. [名前] 列をクリックし、「Id」と入力します。

  8. [ データ型 ] 列で、[ int] を選択します。

  9. [ 主キーですか? ] オプションと [ 識別しますか? ] オプションを [ はい] に設定します。

    名前が示すように、 Is Primary Key は 、これがテーブルの主キーであることをデータベースに伝えます。 Is Identity は 、新しいレコードごとに ID 番号を自動的に作成し、次のシーケンシャル番号 (1 から始まる) を割り当てるようデータベースに指示します。

  10. 次の行をクリックします。 エディターが新しい列定義を開始します。

  11. [名前] の値に「Name」と入力します。

  12. [ データ型] で [nvarchar] を選択し、長さを 50 に設定します。 の nvarcharvar 部分は、この列のデータがレコードごとにサイズが異なる可能性がある文字列であることをデータベースに通知します。 ( n プレフィックスは national を表し、フィールドが任意のアルファベットまたは書き込みシステムを表す文字データを保持できることを示します。つまり、フィールドは Unicode データを保持します)。

  13. [ Null を許可] オプションを [いいえ] に設定します。 これにより、[ 名前] 列が空白のままではなくなります。

  14. この同じプロセスを使用して、Description という名前の列を作成 します。 長さとして データ型 を "nvarchar" に、長さを 50 に設定し、 Null を許可 するを false に設定します。

  15. Price という名前の列を作成します。 [データ型] を "money" に設定し、[Null を許可] を false に設定します。

  16. 上部のボックスで、テーブルに「Product」という名前を付けます。

    完了すると、定義は次のようになります。

    [完了時の定義の外観を示すスクリーンショット。]

  17. Ctrl + S キーを押してテーブルを保存します。

データベースへのデータの追加

これで、この記事の後半で使用するサンプル データをデータベースに追加できます。

  1. 左側のウィンドウで、 SmallBakery.sdf ノードを展開し、[ テーブル] をクリックします。

  2. Product テーブルを右クリックし、[ データ] をクリックします。

  3. 編集ウィンドウで、次のレコードを入力します。

    名前 説明 価格
    パン 毎日焼き上げます。 2.99
    ストロベリーショートケーキ 庭の有機イチゴで作られています。 9.99
    アップルパイ お母さんのパイに次ぎ。 12.99
    ペカンパイ あなたがペカンが好きなら、これはあなたのためのものです。 10.99
    レモンパイ 世界で最高のレモンで作られています。 11.99
    カップケーキ あなたの子供とあなたの中の子供はこれらを愛するでしょう。 7.99

    Id 列には何も入力する必要はないので注意してください。 Id 列を作成するときに、Is Identity プロパティを true に設定すると、自動的に入力されます。

    データの入力が完了すると、テーブル デザイナーは次のようになります。

    [データの入力が完了したときに、テーブル デザイナーの外観を示すスクリーンショット。]

  4. データベース データを含むタブを閉じます。

データベースからのデータの表示

データを含むデータベースを取得したら、ASP.NET Web ページにデータを表示できます。 表示するテーブル行を選択するには、データベースに渡すコマンドである SQL ステートメントを使用します。

  1. 左側のウィンドウで、[ ファイル ] ワークスペースをクリックします。

  2. Web サイトのルートで、 ListProducts.cshtml という名前の新しい CSHTML ページを作成します。

  3. 既存のマークアップを次のように置き換えます。

    @{
        var db = Database.Open("SmallBakery");
        var selectQueryString = "SELECT * FROM Product ORDER BY Name";
     }
    <!DOCTYPE html>
    <html>
     <head>
       <title>Small Bakery Products</title>
       <style>
           table, th, td {
             border: solid 1px #bbbbbb;
             border-collapse: collapse;
             padding: 2px;
           }
        </style>
     </head>
     <body>
       <h1>Small Bakery Products</h1>
       <table>
           <thead>
               <tr>
                   <th>Id</th>
                   <th>Product</th>
                   <th>Description</th>
           <th>Price</th>
               </tr>
           </thead>
           <tbody>
               @foreach(var row in db.Query(selectQueryString)){
                <tr>
                   <td>@row.Id</td>
                       <td>@row.Name</td>
                       <td>@row.Description</td>
                       <td>@row.Price</td>
                </tr>
               }
           </tbody>
       </table>
     </body>
    </html>
    

    最初のコード ブロックで、前に作成した SmallBakery.sdf ファイル (データベース) を開きます。 メソッドは Database.Open.sdf ファイルが Web サイトの App_Data フォルダーにあることを前提としています。 ( .sdf 拡張子を指定する必要はありません。実際、指定した場合、 Open メソッドは機能しません)。

    Note

    App_Data フォルダーは、データ ファイルの格納に使用される ASP.NET 内の特別なフォルダーです。 詳細については、この記事で後述 する「データベースへの接続 」を参照してください。

    次に、次の SQL Select ステートメントを使用してデータベースに対してクエリを実行する要求を行います。

    SELECT * FROM Product ORDER BY Name
    

    ステートメントで、 Product クエリを実行するテーブルを識別します。 文字は * 、クエリがテーブルからすべての列を返すように指定します。 (列の一部のみを表示する場合は、コンマで区切って個別に列を一覧表示することもできます)。句は Order By 、データの並べ替え方法 (この場合は Name 列) を示します。 つまり、各行の Name 列の値に基づいて、データがアルファベット順に並べ替えられます。

    ページの本文で、マークアップによって、データの表示に使用される HTML テーブルが作成されます。 要素内では <tbody> 、ループを foreach 使用して、クエリによって返される各データ行を個別に取得します。 データ行ごとに、HTML テーブル行 (<tr> 要素) を作成します。 次に、各列の HTML テーブル セル (<td> 要素) を作成します。 ループを実行するたびに、データベースから次に使用可能な行が変数に row 格納されます (これは ステートメントで foreach 設定します)。 行から個々の列を取得するには、 または または row.Description を使用row.Nameして、必要な列の名前を指定できます。

  4. ブラウザーでページを実行します。 (ページを実行する前に、[ ファイル ] ワークスペースでページが選択されていることを確認してください)。ページには、次のような一覧が表示されます。

    [ページがブラウザーに表示される一覧を示すスクリーンショット。]

ヒント

構造化照会言語 (SQL)

SQL は、データベース内のデータを管理するためにほとんどのリレーショナル データベースで使用される言語です。 これには、データを取得して更新し、データベース テーブルを作成、変更、管理できるコマンドが含まれています。 SQL はプログラミング言語 (WebMatrix で使用している言語など) とは異なります。SQL では、必要な内容をデータベースに伝え、データを取得またはタスクを実行する方法を見極めるのがデータベースの仕事であるためです。 いくつかの SQL コマンドの例とその実行内容を次に示します。

SELECT Id, Name, Price FROM Product WHERE Price > 10.00 ORDER BY Name

これにより、Price の値が 10 を超える場合、Product テーブルのレコードから IdNamePrice の各列がフェッチされ、Name 列の値に基づいて結果がアルファベット順に返されます。 このコマンドは、条件を満たすレコードを含む結果セットを返します。一致するレコードがない場合は空のセットを返します。

INSERT INTO Product (Name, Description, Price) VALUES ("Croissant", "A flaky delight", 1.99)

これにより 、Product テーブルに新しいレコードが挿入され、 Name 列が "クロワッサン" に、 Description 列が "A flaky delight" に設定され、価格が 1.99 に設定されます。

DELETE FROM Product WHERE ExpirationDate < "01/01/2008"

このコマンドは、有効期限列が 2008 年 1 月 1 日より前の Product テーブルのレコードを削除します。 (これは、 当然ながら Product テーブルにこのような列があることを前提としています)。日付は MM/DD/YYYY 形式でここに入力されますが、ロケールに使用される形式で入力する必要があります。

Insert Intoコマンドと Delete コマンドは結果セットを返しません。 代わりに、コマンドの影響を受けたレコードの数を示す数値を返します。

これらの操作の一部 (レコードの挿入や削除など) の場合、操作を要求するプロセスには、データベースで適切なアクセス許可が必要です。 このため、運用データベースの場合は、データベースに接続するときにユーザー名とパスワードを指定する必要があることがよくあります。

SQL コマンドは多数ありますが、これらはすべて次のようなパターンに従います。 SQL コマンドを使用すると、データベース テーブルの作成、テーブル内のレコード数のカウント、価格の計算、さらに多くの操作の実行を行うことができます。

データベースへのデータの挿入

このセクションでは、ユーザーが Product データベース テーブル に新しい製品を追加できるページを作成する方法について説明します。 新しい製品レコードが挿入されると、前のセクションで作成した ListProducts.cshtml ページを使用して、更新されたテーブルがページに表示されます。

このページには、ユーザーが入力したデータがデータベースに対して有効であることを確認するための検証が含まれています。 たとえば、ページのコードでは、必要なすべての列に値が入力されていることを確認します。

  1. Web サイトで、 InsertProducts.cshtml という名前の新しい CSHTML ファイルを作成します。

  2. 既存のマークアップを次のように置き換えます。

    @{
        Validation.RequireField("Name", "Product name is required.");
        Validation.RequireField("Description", "Product description is required.");
        Validation.RequireField("Price", "Product price is required.");
    
        var db = Database.Open("SmallBakery");
        var Name = Request.Form["Name"];
        var Description = Request.Form["Description"];
        var Price = Request.Form["Price"];
    
        if (IsPost && Validation.IsValid()) {
            // Define the insert query. The values to assign to the
            // columns in the Product table are defined as parameters
            // with the VALUES keyword.
            if(ModelState.IsValid) {
                var insertQuery = "INSERT INTO Product (Name, Description, Price) " +
                    "VALUES (@0, @1, @2)";
                db.Execute(insertQuery, Name, Description, Price);
                // Display the page that lists products.
                Response.Redirect("~/ListProducts");
            }
        }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
     <title>Add Products</title>
     <style type="text/css">
        label {float:left; width: 8em; text-align: right;
               margin-right: 0.5em;}
        fieldset {padding: 1em; border: 1px solid; width: 50em;}
        legend {padding: 2px 4px; border: 1px solid; font-weight:bold;}
        .validation-summary-errors {font-weight:bold; color:red;
               font-size: 11pt;}
     </style>
    </head>
    <body>
     <h1>Add New Product</h1>
    
     @Html.ValidationSummary("Errors with your submission:")
    
     <form method="post" action="">
       <fieldset>
         <legend>Add Product</legend>
         <div>
           <label>Name:</label>
           <input name="Name" type="text" size="50" value="@Name" />
         </div>
         <div>
           <label>Description:</label>
           <input name="Description" type="text" size="50"
               value="@Description" />
         </div>
         <div>
           <label>Price:</label>
           <input name="Price" type="text" size="50" value="@Price" />
         </div>
         <div>
           <label>&nbsp;</label>
           <input type="submit" value="Insert" class="submit" />
         </div>
       </fieldset>
     </form>
    </body>
    </html>
    

    ページの本文には、ユーザーが名前、説明、価格を入力できる 3 つのテキスト ボックスを含む HTML フォームが含まれています。 ユーザーが [ 挿入 ] ボタンをクリックすると、ページの上部にあるコードによって SmallBakery.sdf データベースへの接続が開きます。 次に、 オブジェクトを使用してユーザーが送信した値を Request 取得し、それらの値をローカル変数に割り当てます。

    ユーザーが必要な列ごとに値を入力したことを検証するには、検証する各 <input> 要素を登録します。

    Validation.RequireField("Name", "Product name is required.");
    Validation.RequireField("Description", "Product description is required.");
    Validation.RequireField("Price", "Product price is required.");
    

    ヘルパーは Validation 、登録した各フィールドに値があることを確認します。 すべてのフィールドが検証に合格したかどうかをテストするには、 をチェック Validation.IsValid()します。これは、通常、ユーザーから取得した情報を処理する前に行います。

    if (IsPost && Validation.IsValid()) {
        // Process information here
    }
    

    (演算子は && AND を意味します。このテストは 、これがフォーム送信であり、すべてのフィールドが検証に合格した場合です)。

    すべての列が検証された場合 (空ではなかった場合)、次に示すように SQL ステートメントを作成してデータを挿入し、それを実行します。

    var insertQuery =
        "INSERT INTO Product (Name, Description, Price) VALUES (@0, @1, @2)";
    

    挿入する値には、パラメーター プレースホルダー (@0、、@1@2) を含めます。

    Note

    セキュリティ上の予防措置として、前の例に示すように、パラメーターを使用して常に値を SQL ステートメントに渡します。 これにより、ユーザーのデータを検証する機会が与えられます。また、悪意のあるコマンドをデータベースに送信する試み (SQL インジェクション攻撃とも呼ばれることもあります) から保護するのに役立ちます。

    クエリを実行するには、次のステートメントを使用して、プレースホルダーの代わりに値を含む変数を渡します。

    db.Execute(insertQuery, Name, Description, Price);
    

    ステートメントが Insert Into 実行されたら、次の行を使用して製品を一覧表示するページにユーザーを送信します。

    Response.Redirect("~/ListProducts");
    

    検証が成功しなかった場合は、挿入をスキップします。 代わりに、ページにヘルパーがあり、蓄積されたエラー メッセージ (存在する場合) を表示できます。

    @Html.ValidationSummary("Errors with your submission:")
    

    マークアップのスタイル ブロックに という名前 .validation-summary-errorsの CSS クラス定義が含まれていることに注意してください。 これは、検証エラーを含む要素に既定 <div> で使用される CSS クラスの名前です。 この場合、CSS クラスは検証の概要エラーを赤と太字で表示することを指定しますが、 クラスを定義して任意の .validation-summary-errors 書式を表示できます。

挿入ページのテスト

  1. ブラウザーでページを表示します。 ページには、次の図に示すようなフォームが表示されます。

    [スクリーンショットは、ブラウザーのページに表示されるフォームを示しています。]

  2. すべての列の値を入力しますが、[ 価格 ] 列は空白のままにしてください。

  3. [挿入] をクリックします。 次の図に示すように、ページにエラー メッセージが表示されます。 (新しいレコードは作成されません。

    [スクリーンショットはエラー メッセージを示しています。]

  4. フォームに完全に入力し、[ 挿入] をクリックします。 今回は、 ListProducts.cshtml ページが表示され、新しいレコードが表示されます。

データベース内のデータの更新

テーブルにデータを入力したら、更新が必要になる場合があります。 この手順では、前にデータ挿入用に作成したページと似た 2 つのページを作成する方法を示します。 最初のページには製品が表示され、ユーザーは変更する製品を選択できます。 2 番目のページでは、ユーザーが実際に編集を行って保存できます。

Note

大事な 運用 Web サイトでは、通常、データの変更を許可するユーザーを制限します。 メンバーシップを設定する方法と、ユーザーがサイトでタスクを実行することを承認する方法については、「ASP.NET Web ページ サイトへのセキュリティとメンバーシップの追加」を参照してください。

  1. Web サイトで、 EditProducts.cshtml という名前の新しい CSHTML ファイルを作成します。

  2. ファイル内の既存のマークアップを次のように置き換えます。

    @{
        var db = Database.Open("SmallBakery");
        var selectQueryString = "SELECT * FROM Product ORDER BY Name";
    
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Edit Products</title>
        <style type="text/css">
            table, th, td {
              border: solid 1px #bbbbbb;
              border-collapse: collapse;
              padding: 2px;
            }
        </style>
    </head>
    <body>
        <h1>Edit Small Bakery Products</h1>
        <table>
          <thead>
            <tr>
              <th>&nbsp;</th>
              <th>Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            @foreach (var row in db.Query(selectQueryString)) {
              <tr>
                <td><a href="@Href("~/UpdateProducts", row.Id)">Edit</a></td>
                <td>@row.Name</td>
                <td>@row.Description</td>
                <td>@row.Price</td>
              </tr>
            }
          </tbody>
        </table>
    </body>
    </html>
    

    このページと以前の ListProducts.cshtml ページの唯一の違いは、このページの HTML テーブルに [編集] リンクを表示する追加の列が含まれていることです。 このリンクをクリックすると、選択したレコードを編集できる UpdateProducts.cshtml ページ (次に作成します) に移動します。

    [編集] リンクを作成するコードを見てください。

    <a href="@Href("~/UpdateProducts", row.Id)">Edit</a></td>
    

    これにより、属性がhref動的に設定される HTML <a> 要素が作成されます。 属性は href 、ユーザーがリンクをクリックしたときに表示するページを指定します。 また、現在の Id 行の値もリンクに渡されます。 ページを実行すると、ページ ソースに次のようなリンクが含まれる場合があります。

    <a href="UpdateProducts/1">Edit</a></td>
    <a href="UpdateProducts/2">Edit</a></td>
    <a href="UpdateProducts/3">Edit</a></td>
    

    属性が href に設定されていることに UpdateProducts/n注意してください。 ここで、n は製品番号です。 ユーザーがこれらのリンクのいずれかをクリックすると、結果の URL は次のようになります。

    http://localhost:18816/UpdateProducts/6

    つまり、編集する製品番号が URL に渡されます。

  3. ブラウザーでページを表示します。 ページには、次のような形式でデータが表示されます。

    [ブラウザーのページに表示されるデータを示すスクリーンショット。]

    次に、ユーザーが実際にデータを更新できるようにするページを作成します。 更新ページには、ユーザーが入力したデータを検証するための検証が含まれています。 たとえば、ページ内のコードでは、必要なすべての列に値が入力されていることを確認します。

  4. Web サイトで、 UpdateProducts.cshtml という名前の新しい CSHTML ファイルを作成します。

  5. ファイル内の既存のマークアップを次のように置き換えます。

    @{
        Validation.RequireField("Name", "Product name is required.");
        Validation.RequireField("Description", "Product description is required.");
        Validation.RequireField("Price", "Product price is required.");
    
        var Name = "";
        var Description = "";
        var Price = Decimal.Zero;
    
        var ProductId  = UrlData[0];
        if (ProductId.IsEmpty()) {
             Response.Redirect("~/EditProducts");
        }
    
        var db = Database.Open("SmallBakery");
    
        if (IsPost && Validation.IsValid()) {
            var updateQueryString =
                "UPDATE Product SET Name=@0, Description=@1, Price=@2 WHERE Id=@3" ;
            Name = Request["Name"];
            Description = Request["Description"];
            Price = Request["Price"].AsDecimal();
            db.Execute(updateQueryString, Name, Description, Price, ProductId);
            Response.Redirect(@Href("~/EditProducts"));
        }
        else {
            var selectQueryString = "SELECT * FROM Product WHERE Id=@0";
    
            var row = db.QuerySingle(selectQueryString, ProductId);
            Name = row.Name;
            Description = row.Description;
            Price = row.Price;
        }
    
    }
    
    <!DOCTYPE html>
    <html>
    <head>
      <title>Add Products</title>
      <style type="text/css">
         label { float: left; width: 8em; text-align: right;
                 margin-right: 0.5em;}
         fieldset { padding: 1em; border: 1px solid; width: 35em;}
         legend { padding: 2px 4px;  border: 1px solid; font-weight: bold;}
         .validation-summary-errors {font-weight:bold; color:red; font-size:11pt;}
      </style>
    </head>
    <body>
      <h1>Update Product</h1>
       @Html.ValidationSummary("Errors with your submission:")
       <form method="post" action="">
         <fieldset>
           <legend>Update Product</legend>
           <div>
             <label>Name:</label>
             <input name="Name" type="text" size="50" value="@Name" />
           </div>
           <div>
             <label>Description:</label>
             <input name="Description" type="text" size="50"
                value="@Description" />
           </div>
           <div>
              <label>Price:</label>
              <input name="Price" type="text" size="50" value="@Price" />
           </div>
           <div>
              <label>&nbsp;</label>
              <input type="submit" value="Update" class="submit" />
           </div>
        </fieldset>
      </form>
    </body>
    </html>
    

    ページの本文には、製品が表示され、ユーザーが編集できる HTML フォームが含まれています。 製品を表示するには、次の SQL ステートメントを使用します。

    SELECT * FROM Product WHERE Id=@0
    

    これにより、 パラメーターで渡される値と一致する ID を持つ製品が @0 選択されます。 ( ID は主キーであるため、一意である必要があるため、この方法で選択できる製品レコードは 1 つだけです)。この Select ステートメントに渡す ID 値を取得するには、次の構文を使用して、URL の一部としてページに渡される値を読み取ることができます。

    var ProductId  = UrlData[0];
    

    製品レコードを実際にフェッチするには、 メソッドを QuerySingle 使用します。このメソッドは 1 つのレコードのみを返します。

    var row = db.QuerySingle(selectQueryString, ProductId);
    

    1 つの行が 変数に row 返されます。 各列からデータを取得し、次のようにローカル変数に割り当てることができます。

    var Name = row.Name;
    var Description = row.Description;
    var Price = row.Price;
    

    フォームのマークアップでは、次のような埋め込みコードを使用して、これらの値が個々のテキスト ボックスに自動的に表示されます。

    <input name="Name" type="text" size="50" value="@Name" />
    

    コードのその部分には、更新する製品レコードが表示されます。 レコードが表示されたら、ユーザーは個々の列を編集できます。

    ユーザーが [更新 ] ボタンをクリックしてフォームを送信すると、ブロック内のコードが if(IsPost) 実行されます。 これにより、 オブジェクトからユーザーの値を Request 取得し、値を変数に格納し、各列が入力されたことを検証します。 検証に合格すると、次の SQL Update ステートメントが作成されます。

    UPDATE Product SET Name=@0, Description=@1, Price=@2, WHERE ID=@3
    

    SQL Update ステートメントでは、更新する各列と、それを設定する値を指定します。 このコードでは、パラメーター プレースホルダー @0@1@2、、などを使用して値を指定します。 (前に説明したように、セキュリティ上、常にパラメーターを使用して SQL ステートメントに値を渡す必要があります)。

    メソッドを db.Execute 呼び出すときは、SQL ステートメントのパラメーターに対応する順序で値を含む変数を渡します。

    db.Execute(updateQueryString, Name, Description, Price, ProductId);
    

    ステートメントが Update 実行されたら、次のメソッドを呼び出して、ユーザーを編集ページにリダイレクトします。

    Response.Redirect(@Href("~/EditProducts"));
    

    その結果、ユーザーはデータベース内のデータの更新された一覧を表示し、別の製品を編集できます。

  6. ページを保存します。

  7. (更新ページではなく) EditProducts.cshtml ページを実行し、[ 編集 ] をクリックして編集する製品を選択します。 UpdateProducts.cshtml ページが表示され、選択したレコードが表示されます。

    [選択したレコードと共に [製品の更新] ページを示すスクリーンショット。

  8. 変更を加え、[ 更新] をクリックします。 製品の一覧が、更新されたデータと共に再び表示されます。

データベース内のデータの削除

このセクションでは、ユーザーが Product データベース テーブルから製品を削除できるようにする方法について説明します。 この例は、2 つのページで構成されています。 最初のページでは、ユーザーは削除するレコードを選択します。 削除するレコードが 2 ページ目に表示され、レコードを削除することを確認できます。

Note

大事な 運用 Web サイトでは、通常、データの変更を許可するユーザーを制限します。 メンバーシップを設定する方法と、ユーザーがサイトでタスクを実行することを承認する方法については、「ASP.NET Web ページ サイトへのセキュリティとメンバーシップの追加」を参照してください。

  1. Web サイトで、 ListProductsForDelete.cshtml という名前の新しい CSHTML ファイルを作成します。

  2. 既存のマークアップを次のように置き換えます。

    @{
      var db = Database.Open("SmallBakery");
      var selectQueryString = "SELECT * FROM Product ORDER BY Name";
    }
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delete a Product</title>
        <style>
            table, th, td {
              border: solid 1px #bbbbbb;
              border-collapse: collapse;
              padding: 2px;
            }
         </style>
    </head>
    <body>
      <h1>Delete a Product</h1>
      <form method="post" action="" name="form">
        <table border="1">
          <thead>
            <tr>
              <th>&nbsp;</th>
              <th>Name</th>
              <th>Description</th>
              <th>Price</th>
            </tr>
          </thead>
          <tbody>
            @foreach (var row in db.Query(selectQueryString)) {
              <tr>
                <td><a href="@Href("~/DeleteProduct", row.Id)">Delete</a></td>
                <td>@row.Name</td>
                <td>@row.Description</td>
                <td>@row.Price</td>
              </tr>
            }
          </tbody>
        </table>
      </form>
    </body>
    </html>
    

    このページは、以前の EditProducts.cshtml ページに似ています。 ただし、各製品の [編集] リンクを表示する代わりに、[ 削除] リンクが表示されます。 [削除] リンクは、マークアップに次の埋め込みコードを使用して作成されます。

    <a href="@Href("~/DeleteProduct", row.Id)">Delete</a>
    

    これにより、ユーザーがリンクをクリックすると、次のような URL が作成されます。

    http://<server>/DeleteProduct/4

    URL は DeleteProduct.cshtml という名前のページを呼び出し (次に作成します)、削除する製品の ID を渡します (ここでは 4)。

  3. ファイルを保存しますが、開いたままにします。

  4. DeleteProduct.cshtml という名前の別の CHTML ファイルを作成します。 既存のコンテンツを次のように置き換えます。

    @{
      var db = Database.Open("SmallBakery");
      var ProductId = UrlData[0];
      if (ProductId.IsEmpty()) {
        Response.Redirect("~/ListProductsForDelete");
      }
      var prod = db.QuerySingle("SELECT * FROM PRODUCT WHERE ID = @0", ProductId);
      if( IsPost && !ProductId.IsEmpty()) {
        var deleteQueryString = "DELETE FROM Product WHERE Id=@0";
        db.Execute(deleteQueryString, ProductId);
        Response.Redirect("~/ListProductsForDelete");
      }
    }
    
    <!DOCTYPE html>
    <html>
    <head>
        <title>Delete Product</title>
    </head>
    <body>
      <h1>Delete Product - Confirmation</h1>
      <form method="post" action="" name="form">
        <p>Are you sure you want to delete the following product?</p>
    
        <p>Name: @prod.Name <br />
           Description: @prod.Description <br />
           Price: @prod.Price</p>
        <p><input type="submit" value="Delete" /></p>
      </form>
    </body>
    </html>
    

    このページは ListProductsForDelete.cshtml によって呼び出され、ユーザーは製品を削除することを確認できます。 削除する製品を一覧表示するには、次のコードを使用して、URL から削除する製品の ID を取得します。

    var ProductId = UrlData[0];
    

    その後、ページは、実際にレコードを削除するボタンをクリックするようにユーザーに求めます。 これは重要なセキュリティ対策です。データの更新や削除などの機密性の高い操作を Web サイトで実行する場合、これらの操作は常に GET 操作ではなく POST 操作を使用して行う必要があります。 GET 操作を使用して削除操作を実行できるようにサイトが設定されている場合は、 などの http://<server>/DeleteProduct/4 URL を渡し、データベースから必要なものは誰でも削除できます。 確認を追加し、POST を使用してのみ削除を実行できるようにページをコーディングすることで、サイトにセキュリティ対策を追加します。

    実際の削除操作は次のコードを使用して実行されます。最初に、これが事後操作であり、ID が空ではないことを確認します。

    if( IsPost && !ProductId.IsEmpty()) {
        var deleteQueryString = "DELETE FROM Product WHERE Id=@0";
        db.Execute(deleteQueryString, ProductId);
        Response.Redirect("~/ListProductsForDelete");
    }
    

    コードは、指定されたレコードを削除し、ユーザーをリスト ページにリダイレクトする SQL ステートメントを実行します。

  5. ブラウザーで ListProductsForDelete.cshtml を実行します。

    [ブラウザーでの削除ドット CSHTML のリスト製品の実行を示すスクリーンショット。]

  6. いずれかの製品の [削除] リンクをクリックします。 DeleteProduct.cshtml ページが表示され、そのレコードを削除することを確認します。

  7. [削除] ボタンをクリックします。 製品レコードが削除され、更新された製品一覧でページが更新されます。

ヒント

データベースに接続する

2 つの方法でデータベースに接続できます。 1 つ目は、 メソッドを Database.Open 使用し、データベース ファイルの名前を指定することです ( 拡張子は .sdf 未満)。

var db = Database.Open("SmallBakery");

メソッドは Open 、 を前提としています。sdf ファイルは、Web サイトの App_Data フォルダーにあります。 このフォルダーは、データを保持するために特別に設計されています。 たとえば、Web サイトでデータの読み取りと書き込みを許可するための適切なアクセス許可があり、セキュリティ対策として、WebMatrix はこのフォルダーからファイルへのアクセスを許可しません。

2 つ目の方法は、接続文字列を使用する方法です。 データベースに接続する方法に関する情報が含まれる接続文字列。 これには、ファイル パスを含めることができます。または、ローカル サーバーまたはリモート サーバー上のSQL Server データベースの名前と、そのサーバーに接続するためのユーザー名とパスワードを含めることができます。 (ホスティング プロバイダーのサイトなど、SQL Serverの一元管理バージョンにデータを保持する場合は、常に接続文字列を使用してデータベース接続情報を指定します)。

WebMatrix では、接続文字列は通常、 という名前の XML ファイル Web.config格納されます。名前が示すように、Web サイトのルートにある Web.config ファイルを使用して、サイトに必要な接続文字列など、サイトの構成情報を格納できます。 Web.config ファイル内の接続文字列の例を次に示します。 注 $CREDENTIAL_PLACEHOLDER$ は、パスワード キーと値のペアのプレースホルダーです。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
   <add
     name="SQLServerConnectionString"
     connectionString= "server=myServer;database=myDatabase;uid=username;$CREDENTIAL_PLACEHOLDER$"
     providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

この例では、接続文字列は、(ローカルの .sdf ファイルではなく) どこかのサーバーで実行されているSQL Serverのインスタンス内のデータベースを指しています。 と myDatabaseの適切な名前myServerに置き換え、 と のログイン値SQL Server指定するusernamepassword必要があります。 (ユーザー名とパスワードの値は、Windows の資格情報や、ホスティング プロバイダーがサーバーにログインするために指定した値と必ずしも同じとは限りません。必要な正確な値については、管理者に確認してください)。

このメソッドは Database.Open 柔軟です。これは、データベース の .sdf ファイルの名前または Web.config ファイルに格納されている接続文字列の名前を渡すことができるためです。 次の例は、前の例で示した接続文字列を使用してデータベースに接続する方法を示しています。

@{
    var db = Database.Open("SQLServerConnectionString");
}

説明したように、 メソッドを Database.Open 使用すると、データベース名または接続文字列を渡すことができます。どちらを使用するかを確認できます。 これは、Web サイトをデプロイ (発行) するときに非常に便利です。 サイトを開発およびテストするときに、App_Data フォルダー内の .sdf ファイルを使用できます。 その後、サイトを運用サーバーに移動するときに、.sdf ファイルと同じ名前を持ち、ホスティング プロバイダーのデータベースを指す接続文字列をWeb.config ファイルで使用できます。コードを変更する必要はありません。

最後に、接続文字列を直接操作する場合は、 メソッドを Database.OpenConnectionString 呼び出し、 Web.config ファイル内の名前ではなく、実際の接続文字列を渡すことができます。 これは、何らかの理由で、ページが実行されるまで接続文字列 (またはその中の値 ( .sdf ファイル名など) にアクセスできない場合に役立ちます。 ただし、ほとんどのシナリオでは、この記事の説明に従って を使用 Database.Open できます。

その他のリソース