ASP.NET MVC アプリケーションでの Entity Framework での並べ替え、フィルター処理、ページング (3/10)

作成者: Tom Dykstra

Contoso University サンプル Web アプリケーションでは、Entity Framework 5 Code First と Visual Studio 2012 を使用して、ASP.NET MVC 4 アプリケーションを作成する方法を示します。 チュートリアル シリーズについては、シリーズの最初のチュートリアルをご覧ください。

Note

解決できない問題が発生した場合は、 完了した章をダウンロード して、問題を再現してみてください。 一般に、コードを完成したコードと比較することで、問題の解決策を見つけることができます。 一般的なエラーとその解決方法については、「エラーと回避策」を参照してください。

前のチュートリアルでは、エンティティの基本的な CRUD 操作用の一連の Web ページを Student 実装しました。 このチュートリアルでは、[ 学生 のインデックス] ページに並べ替え、フィルター処理、ページング機能を追加します。 単純なグループ化を実行するページも作成します。

次の図は、作業が終了したときにページがどのように表示されるかを示しています。 列見出しとは、ユーザーがクリックしてその列で並べ替えを行うことができるリンクです。 列見出しを繰り返しクリックすると、昇順と降順の並べ替え順序が切り替えられます。

Students_Index_page_with_paging

学生インデックス ページに並べ替えを追加するには、コントローラーの メソッドをIndex変更し、インデックス ビューにコードをStudent追加Studentします。

Index メソッドに並べ替え機能を追加する

Controllers\StudentController.cs で、 メソッドをIndex次のコードに置き換えます。

public ActionResult Index(string sortOrder)
{
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";
   var students = from s in db.Students
                  select s;
   switch (sortOrder)
   {
      case "Name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "Date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:
         students = students.OrderBy(s => s.LastName);
         break;
   }
   return View(students.ToList());
}

このコードは、URL 内の文字列から sortOrder パラメーターを受け取ります。 クエリ文字列の値は、アクション メソッド ASP.NET パラメーターとして MVC によって提供されます。 パラメータは、"Name" または "Date" という文字列で、その後に必要に応じてアンダースコアと降順を指定する文字列 "desc" が続きます。 既定の並べ替え順序は昇順です。

インデックス ページが初めて要求されたときには、クエリ文字列はありません。 学生は、 によって LastName昇順に表示されます。これは、 ステートメントのフォールスルー ケース switch によって確立される既定値です。 ユーザーが列見出しハイパーリンクをクリックすると、適切な sortOrder 値がクエリ文字列で提供されます。

ビューが適切なクエリ文字列値を使用して列見出しハイパーリンクを構成できるように、2 つの ViewBag 変数が使用されます。

ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "Name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "Date_desc" : "Date";

これらは、三項ステートメントです。 1 つ目は、パラメーターが null または空の場合 sortOrder は、 ViewBag.NameSortParm "name_desc" に設定する必要があることを指定します。それ以外の場合は、空の文字列に設定する必要があります。 これらの 2 つのステートメントを使用して、次のようにビューで列見出しのハイパーリンクの設定することができます。

既定の並べ替え順 姓のハイパーリンク 日付のハイパーリンク
姓の昇順 descending ascending
姓の降順 ascending ascending
日付の昇順 ascending descending
日付の降順 ascending ascending

メソッドは、LINQ to Entitiesを使用して、並べ替えの基準となる列を指定します。 このコードでは、 ステートメントの前に IQueryable 変数をswitch作成し、 ステートメントでswitch変更し、 ステートメントの後に メソッドをToListswitch呼び出します。 IQueryable 変数を作成および変更するときに、データベースに送信されるクエリはありません。 などのToListメソッドを呼び出してオブジェクトをIQueryableコレクションに変換するまで、クエリは実行されません。 したがって、このコードでは、 ステートメントまで return View 実行されないクエリが 1 つになります。

Views\Student\Index.cshtml で、見出し行の <tr> および <th> 要素を強調表示されたコードに置き換えます。

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table>
    <tr>
        <th>
            @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.NameSortParm })
        </th>
        <th>First Name
        </th>
        <th>
            @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm })
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {

このコードでは、 プロパティの情報を ViewBag 使用して、適切なクエリ文字列値を含むハイパーリンクを設定します。

ページを実行し、[姓] 列と [登録日] 列見出しをクリックして、並べ替えが機能することを確認します。

Contoso University Students の [インデックス] ページを示すスクリーンショット。列見出しは、姓、名、および登録日です。

[姓] 見出しをクリックすると、学生は姓の降順で表示されます。

Contoso University Students Index ページを示すスクリーンショット。学生の一覧が姓の降順で表示されています。

Students インデックス ページに検索ボックスを追加する

Students インデックス ページにフィルターを追加するには、テキスト ボックスと送信ボタンをビューに追加し、Index メソッドで対応する変更を行います。 テキスト ボックスを使用して、姓と名のフィールドに検索する文字列を入力できます。

Index メソッドにフィルター機能を追加する

Controllers\StudentController.cs で、 メソッドをIndex次のコードに置き換えます (変更が強調表示されています)。

public ViewResult Index(string sortOrder, string searchString)
{
    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
    var students = from s in db.Students
                   select s;
    if (!String.IsNullOrEmpty(searchString))
    {
        students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                               || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
    }
    switch (sortOrder)
    {
        case "name_desc":
            students = students.OrderByDescending(s => s.LastName);
            break;
        case "Date":
            students = students.OrderBy(s => s.EnrollmentDate);
            break;
        case "date_desc":
            students = students.OrderByDescending(s => s.EnrollmentDate);
            break;
        default:
            students = students.OrderBy(s => s.LastName);
            break;
    }

    return View(students.ToList());
}

searchString パラメーターを Index メソッドに追加しました。 また、LINQ ステートメント where に、名または姓に検索文字列が含まれている学生のみを選択する句を追加しました。 検索文字列の値は、インデックス ビューに追加するテキスト ボックスから受け取ります。 where 句を追加するステートメントは、検索する値がある場合にのみ実行されます。

Note

多くの場合、Entity Framework エンティティ セットで同じメソッドを呼び出すか、メモリ内コレクションの拡張メソッドとして呼び出すことができます。 結果は通常同じですが、場合によっては異なる場合があります。 たとえば、 メソッドの.NET Framework実装では、空のContains文字列を渡すとすべての行が返されますが、SQL Server Compact 4.0 の Entity Framework プロバイダーは空の文字列に対して 0 行を返します。 したがって、例のコード (ステートメント内ifに ステートメントをWhere配置する) により、すべてのバージョンのSQL Serverで同じ結果が得られます。 また、メソッドのContains.NET Framework実装では、既定では大文字と小文字が区別される比較が実行されますが、Entity Framework SQL Server プロバイダーでは既定で大文字と小文字を区別しない比較が実行されます。 したがって、 メソッドをToUpper呼び出してテストで明示的に大文字と小文字を区別しないようにすることで、後でリポジトリを使用するようにコードを変更しても結果は変更されません。これにより、オブジェクトではなくIQueryableコレクションが返IEnumerableされます。 (IEnumerable コレクションに対して Contains メソッドを呼び出したときには、.NET Framework の実装を取得します。IQueryable オブジェクトに対して呼び出したときには、データベース プロバイダーの実装を取得します)。

Students インデックス ビューに [Search] ボックスを追加する

Views\Student\Index.cshtml で、強調表示されたコードを開始tableタグの直前に追加して、キャプション、テキスト ボックス、検索ボタンを作成します。

<p>
    @Html.ActionLink("Create New", "Create")
</p>

@using (Html.BeginForm())
{
    <p>
        Find by name: @Html.TextBox("SearchString")  
        <input type="submit" value="Search" /></p>
}

<table>
    <tr>

ページを実行し、検索文字列を入力し、[ 検索 ] をクリックしてフィルター処理が機能していることを確認します。

Students_Index_page_with_search_box

URL に "an" 検索文字列が含まれていないことに注意してください。つまり、このページをブックマークすると、ブックマークを使用してもフィルター処理された一覧は取得されません。 チュートリアルの後半でフィルター条件にクエリ文字列を使用するように [ 検索 ] ボタンを変更します。

学生のインデックス ページにページングを追加する

Students Index ページにページングを追加するには、まず PagedList.Mvc NuGet パッケージをインストールします。 次に、 メソッドに追加の変更を Index 加え、ページング リンクをビューに Index 追加します。 PagedList.Mvc は、ASP.NET MVC 用の多くの優れたページングおよび並べ替えパッケージの 1 つであり、ここでの使用は、他のオプションに対する推奨事項としてではなく、例としてのみ意図されています。 次の図は、ページング リンクを示しています。

ページング リンクを示す [Students Index]\(学生インデックス\) ページのスクリーンショット。

PagedList.MVC NuGet パッケージをインストールする

NuGet PagedList.Mvc パッケージは、 PagedList パッケージを依存関係として自動的にインストールします。 PagedList パッケージは、 および コレクションのPagedListコレクション型と拡張メソッドをIQueryableIEnumerableインストールします。 拡張メソッドは、 または IEnumerableからコレクション内に PagedList 1 ページのデータをIQueryable作成し、PagedListコレクションにはページングを容易にするプロパティとメソッドがいくつか用意されています。 PagedList.Mvc パッケージは、ページング ボタンを表示するページング ヘルパーをインストールします。

[ツール] メニューの [NuGet パッケージ マネージャー] を選択し、[ソリューションの NuGet パッケージの管理] を選択します。

[ NuGet パッケージの管理 ] ダイアログ ボックスで、左側の [ オンライン ] タブをクリックし、検索ボックスに「paged」と入力します。 PagedList.Mvc パッケージが表示されたら、[インストール] をクリックします。

[GET パッケージの管理] ダイアログ ボックスを示すスクリーンショット。[オンライン] タブと、ページに表示された単語が入力された検索バーが強調表示されています。[ページ 一覧] パッケージが選択されています。

[ プロジェクトの選択 ] ボックスで、[ OK] をクリックします

[プロジェクトの選択] ダイアログ ボックスを示すスクリーンショット。[OK] ボタンが選択されています。

Index メソッドにページング機能を追加する

Controllers\StudentController.cs で、名前空間の using ステートメントをPagedList追加します。

using PagedList;

Index メソッドを次のコードに置き換えます。

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
   ViewBag.CurrentSort = sortOrder;
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

   if (searchString != null)
   {
      page = 1;
   }
   else
   {
      searchString = currentFilter;
   }

   ViewBag.CurrentFilter = searchString;

   var students = from s in db.Students
                  select s;
   if (!String.IsNullOrEmpty(searchString))
   {
      students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                             || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
   }
   switch (sortOrder)
   {
      case "name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:  // Name ascending 
         students = students.OrderBy(s => s.LastName);
         break;
   }

   int pageSize = 3;
   int pageNumber = (page ?? 1);
   return View(students.ToPagedList(pageNumber, pageSize));
}

このコードでは、次に示すように、パラメーター、現在の並べ替え順序パラメーター、および現在のフィルター パラメーターをメソッド シグネチャに追加 page します。

public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)

最初にページが表示されるとき、またはユーザーがページングや並べ替えのリンクをクリックしていない場合、すべてのパラメーターは null になります。 ページング リンクがクリックされた場合、 page 変数には表示するページ番号が含まれます。

A ViewBag プロパティは、ページング中に並べ替え順序を同じに保つためにページング リンクに含める必要があるため、ビューに現在の並べ替え順序を提供します。

ViewBag.CurrentSort = sortOrder;

もう 1 つのプロパティ である は、 ViewBag.CurrentFilterビューに現在のフィルター文字列を提供します。 ページング中にフィルターの設定を維持するために、ページングのリンクにこの値を含める必要があり、ページが再表示されるときに、この値をテキスト ボックスに復元する必要があります。 ページングの中に検索文字列を変更した場合は、新しいフィルターのために別のデータが表示されるため、ページを 1 にリセットする必要があります。 テキスト ボックスに値が入力され、[送信] ボタンが押されると、検索文字列が変更されます。 その場合、 searchString パラメーターは null ではありません。

if (searchString != null)
        page = 1;
else
    searchString = currentFilter;

メソッドの末尾にある students オブジェクトの拡張メソッドは、 ToPagedList ページング IQueryable をサポートするコレクション型の学生の 1 ページに学生クエリを変換します。 その後、学生のその 1 ページがビューに渡されます。

int pageSize = 3;
int pageNumber = (page ?? 1);
return View(students.ToPagedList(pageNumber, pageSize));

ToPagedList メソッドは、ページ番号を受け取ります。 2 つの疑問符は 、null 合体演算子を表します。 null 合体演算子は null 許容型の既定値を定義します。式 (page ?? 1) は、値がある場合は page の値を返し、page が null の場合は 1 を返すことを意味します。

Views\Student\Index.cshtml で、既存のコードを次のコードに置き換えます。

@model PagedList.IPagedList<ContosoUniversity.Models.Student>
@using PagedList.Mvc; 
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />

@{
    ViewBag.Title = "Students";
}

<h2>Students</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
}
<table>
<tr>
    <th></th>
    <th>
        @Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })
    </th>
    <th>
        First Name
    </th>
    <th>
        @Html.ActionLink("Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter })
    </th>
</tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.StudentID }) |
            @Html.ActionLink("Details", "Details", new { id=item.StudentID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.StudentID })
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstMidName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
    </tr>
}

</table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

@Html.PagedListPager( Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter=ViewBag.CurrentFilter }) )

ページの上部にある @model ステートメントは、ビューが List オブジェクトの代わりに PagedList オブジェクトを取得するようになったことを指定します。

PagedList.Mvc ステートメントをusing使用すると、ページング ボタンの MVC ヘルパーにアクセスできます。

このコードでは、FormMethod.Get を指定できる BeginForm のオーバーロードを使用します。

@using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
    <p>
        Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)  
        <input type="submit" value="Search" />
    </p>
}

既定の BeginForm は POST を使用してフォーム データを送信します。つまり、パラメーターはクエリ文字列として URL ではなく HTTP メッセージ本文で渡されます。 HTTP GET を指定すると、フォーム データがクエリ文字列として URL で渡され、ユーザーが URL をブックマークできるようになります。 HTTP GET の使用に関する W3C ガイドラインでは、アクションが更新されない場合は GET を使用する必要があることを指定しています。

テキスト ボックスは現在の検索文字列で初期化されるため、新しいページをクリックすると、現在の検索文字列が表示されます。

Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)

列ヘッダーへのリンクは、フィルターの結果内でユーザーが並べ替えられるように、クエリ文字列を使用してコントローラーに現在の検索文字列を渡します。

@Html.ActionLink("Last Name", "Index", new { sortOrder=ViewBag.NameSortParm, currentFilter=ViewBag.CurrentFilter })

現在のページと合計ページ数が表示されます。

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount

表示するページがない場合は、"ページ 0/0" が表示されます。 (その場合、ページ番号は 1 で 0 であるため Model.PageNumberModel.PageCount ページ数がページ数より大きくなります)。

ページング ボタンは、ヘルパーによって PagedListPager 表示されます。

@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )

ヘルパーには PagedListPager 、URL やスタイル設定など、カスタマイズできるさまざまなオプションが用意されています。 詳細については、GitHub サイト の TroyGoode/PagedList を参照してください。

ページを実行します。

[Students Index]\(学生のインデックス\) ページのスクリーンショット。

異なる並べ替え順でページングのリンクをクリックし、ページングが機能することを確認します。 その後で、検索文字列を入力して、ページングをもう一度試し、並べ替えとフィルター処理を使用してもページングが正しく機能することを確認します。

[Students Index]\(学生のインデックス\) ページを示すスクリーンショット。名前で検索する検索バーに、 という単語が入力されます。

学生の統計情報を表示する About ページを作成する

Contoso 大学の Web サイトの [About] ページに、登録日付ごとに登録した受講者の数が表示されます。 これには、グループ化とグループに関する簡単な計算が必要です。 これを実行するためには、次の手順を実行します。

  • ビューに渡す必要があるデータのビュー モデル クラスを作成します。
  • コントローラーの About メソッドを Home 変更します。
  • ビューを変更します About

ビュー モデルを作成する

ViewModels フォルダーを作成します。 そのフォルダーに、クラス ファイル EnrollmentDateGroup.cs を追加し、既存のコードを次のコードに置き換えます。

using System;
using System.ComponentModel.DataAnnotations;

namespace ContosoUniversity.ViewModels
{
    public class EnrollmentDateGroup
    {
        [DataType(DataType.Date)]
        public DateTime? EnrollmentDate { get; set; }

        public int StudentCount { get; set; }
    }
}

Home コントローラーを変更する

HomeController.cs で、ファイルの先頭に次usingのステートメントを追加します。

using ContosoUniversity.DAL;
using ContosoUniversity.ViewModels;

クラスの中かっこの直後に、データベース コンテキストのクラス変数を追加します。

public class HomeController : Controller
{
    private SchoolContext db = new SchoolContext();

About メソッドを次のコードに置き換えます。

public ActionResult About()
{
    var data = from student in db.Students
               group student by student.EnrollmentDate into dateGroup
               select new EnrollmentDateGroup()
               {
                   EnrollmentDate = dateGroup.Key,
                   StudentCount = dateGroup.Count()
               };
    return View(data);
}

LINQ ステートメントは、登録日で受講者エンティティをグループ化し、各グループ内のエンティティの数を計算して、結果を EnrollmentDateGroup ビュー モデル オブジェクトのコレクションに格納します。

メソッドを追加します Dispose

protected override void Dispose(bool disposing)
{
    db.Dispose();
    base.Dispose(disposing);
}

About ビューを変更する

Views\Home\About.cshtml ファイルのコードを次のコードに置き換えます。

@model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
           
@{
    ViewBag.Title = "Student Body Statistics";
}

<h2>Student Body Statistics</h2>

<table>
    <tr>
        <th>
            Enrollment Date
        </th>
        <th>
            Students
        </th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
        <td>
            @item.StudentCount
        </td>
    </tr>
}
</table>

アプリを実行し、[ バージョン情報 ] リンクをクリックします。 登録の日付ごとの学生の数が、テーブルに表示されます。

About_page

省略可能: アプリを Windows Azure にデプロイする

これまで、アプリケーションは開発用コンピューターの IIS Express でローカルで実行されています。 他のユーザーがインターネット経由で使用できるようにするには、Web ホスティング プロバイダーに展開する必要があります。 チュートリアルのこの省略可能なセクションでは、Windows Azure Web サイトにデプロイします。

Code First Migrationsを使用してデータベースをデプロイする

データベースをデプロイするには、Code First Migrationsを使用します。 Visual Studio からデプロイするための設定を構成するために使用する発行プロファイルを作成するときに、[Code First Migrationsの実行 (アプリケーションの起動時に実行)] というラベルの付いたチェック ボックスを選択します。 この設定により、Code First で初期化子クラスが使用されるように、展開プロセスによって、ターゲット サーバー上のアプリケーション Web.config ファイルが自動的に MigrateDatabaseToLatestVersion 構成されます。

Visual Studio は、配置プロセス中にデータベースに対して何も行いません。 デプロイされたアプリケーションがデプロイ後に初めてデータベースにアクセスすると、Code First によってデータベースが自動的に作成されるか、データベース スキーマが最新バージョンに更新されます。 アプリケーションで Migrations Seed メソッドが実装されている場合は、データベースの作成後またはスキーマの更新後に メソッドが実行されます。

Migrations メソッドは Seed テスト データを挿入します。 運用環境にデプロイする場合は、 メソッドを変更 Seed して、運用データベースに挿入するデータのみを挿入する必要があります。 たとえば、現在のデータ モデルでは、実際のコースが必要ですが、開発データベースには架空の学生が必要な場合があります。 開発中に両方を Seed 読み込むメソッドを記述し、運用環境にデプロイする前に架空の学生をコメントアウトできます。 または、コースのみを読み込むメソッドを記述 Seed し、アプリケーションの UI を使用してテスト データベースに架空の学生を手動で入力することもできます。

Windows Azure アカウントを取得する

Windows Azure アカウントが必要です。 まだお持ちでない場合は、わずか数分で無料試用版アカウントを作成できます。 詳細については、「Windows Azure 無料評価版」を参照してください。

Windows Azure で Web サイトと SQL データベースを作成する

Windows Azure Web サイトは共有ホスティング環境で実行されます。つまり、他の Windows Azure クライアントと共有されている仮想マシン (VM) で実行されます。 共有ホスティング環境は、クラウドで開始するための低コストの方法です。 その後、Web トラフィックが増加した場合、アプリケーションは専用 VM 上で実行することで、ニーズに合わせてスケーリングできます。 より複雑なアーキテクチャが必要な場合は、Windows Azure Cloud Service に移行できます。 クラウド サービスは、ニーズに応じて構成できる専用 VM で実行されます。

Windows Azure SQL Database は、SQL Server テクノロジに基づいて構築されたクラウドベースのリレーショナル データベース サービスです。 SQL Serverで動作するツールとアプリケーションも、SQL Databaseで動作します。

  1. Windows Azure 管理ポータルで、左側のタブで [Web サイト] をクリックし、[新規] をクリックします。

    管理ポータルの [新規] ボタン

  2. [ カスタム作成] をクリックします。

    [新規] ダイアログ ボックスを示すスクリーンショット。[Web サイト] オプションと [カスタム作成] オプションが強調表示されています。

    [新しい Web サイト - カスタム作成] ウィザードが開きます。

  3. ウィザードの [新しい Web サイト ] ステップで、[ URL ] ボックスに、アプリケーションの一意の URL として使用する文字列を入力します。 ここに入力した文字列と、このテキスト ボックスの右側に表示されている文字列を組み合わせたものが実際の URL になります。 この図は "ConU" を示していますが、その URL はおそらく取得されるため、別の URL を選択する必要があります。

    管理ポータルで [データベースを使用して作成] リンク

  4. [ リージョン ] ドロップダウン リストで、近くのリージョンを選択します。 この設定では、Web サイトを実行するデータ センターを指定します。

  5. [ データベース ] ドロップダウン リストで、[ Create a free 20 MB SQL database]\(無料の 20 MB SQL データベースの作成\) を選択します。

    [Web サイトの作成] ダイアログ ボックスを示すスクリーンショット。[データベース] ドロップダウン リストで、20 M B S Q L の無料データベースを選択します。[チェック マーク] ボタンが強調表示されています。

  6. [ DB 接続文字列名] に「 SchoolContext」と入力します。

    [Web サイトの作成] ダイアログ ボックスを示すスクリーンショット。[School Context]\(学校コンテキスト\) が [D B 接続文字列名] テキスト フィールドに入力されます。[チェック マーク] ボタンが強調表示されています。

  7. ボックスの下部にある右を指す矢印をクリックします。 ウィザードが [ データベース設定] ステップに進みます。

  8. [ 名前 ] ボックスに「 ContosoUniversityDB」と入力します。

  9. [サーバー] ボックスで、[新しいSQL Database サーバー] を選択します。 または、以前にサーバーを作成した場合は、ドロップダウン リストからそのサーバーを選択できます。

  10. 管理者の ログイン名 とパスワードを入力 します[新しい SQL Database サーバー] を選択した場合は、既存の名前とパスワードではなく、このデータベースへのアクセス時に使用する新しい名前とパスワードを入力してください。 前に作成したサーバーを選択した場合は、そのサーバーの資格情報を入力します。 このチュートリアルでは、[高度なチェック] ボックスは選択しません。 [詳細設定] オプションを使用すると、データベースの照合順序を設定できます

  11. Web サイトに対して選択したのと同じ リージョン を選択します。

  12. ボックスの右下にあるチェックマークをクリックして、完了したことを示します。

    すべての設定が選択され、テキスト フィールドにサンプル パスワードが含まれている [データベース設定の指定] ダイアログ ボックスを示すスクリーンショット。[チェック マーク] ボタンが強調表示されています。

    次の図は、既存のSQL Serverとログインの使用を示しています。

    [新しい Web サイト - データベースを使用して作成] ウィザードの [データベース設定] ステップ

    管理ポータルが [Web サイト] ページに戻り、[ 状態] 列にサイトが作成されていることを示します。 しばらくすると (通常は 1 分未満)、[ 状態] 列にサイトが正常に作成されたことが表示されます。 左側のナビゲーション バーで、アカウント内のサイトの数が [Web サイト ] アイコンの横に表示され、[ SQL データベース ] アイコンの横にデータベースの数が表示されます。

アプリケーションを Windows Azure にデプロイする

  1. Visual Studio のソリューション エクスプローラーで、プロジェクトを右クリックし、コンテキスト メニューの [発行] をクリックします。

    プロジェクトのコンテキスト メニューの [発行]

  2. Web 発行ウィザードの [プロファイル] タブで、[インポート] をクリックします。

    発行設定のインポート

  3. Visual Studio で Windows Azure サブスクリプションを以前に追加していない場合は、次の手順を実行します。 これらの手順では、サブスクリプションを追加して、[ Windows Azure Web サイトからインポート ] のドロップダウン リストに Web サイトが含まれるようにします。

    a. [ 発行プロファイルのインポート ] ダイアログ ボックスで、[ Windows Azure Web サイトからのインポート] をクリックし、[ Windows Azure サブスクリプションの追加] をクリックします。

    Windows Azure サブスクリプションを追加する

    b. [ Windows Azure サブスクリプションのインポート ] ダイアログ ボックスで、[ サブスクリプション ファイルのダウンロード] をクリックします。

    サブスクリプション ファイルのダウンロード

    c. ブラウザー ウィンドウで、 .publishsettings ファイルを 保存します。

    .publishsettings ファイルをダウンロードする

    警告

    セキュリティ - publishsettings ファイルには、Windows Azure サブスクリプションとサービスの管理に使用される資格情報 (エンコードされていない) が含まれています。 このファイルのセキュリティのベスト プラクティスは、ソース ディレクトリの外部 ( Libraries\Documents フォルダーなど) に一時的に保存し、インポートが完了したら削除することです。 ファイルにアクセスできる悪意のあるユーザーは .publishsettings 、Windows Azure サービスを編集、作成、削除できます。

    d. [ Windows Azure サブスクリプションのインポート ] ダイアログ ボックスで、[ 参照 ] をクリックし、 .publishsettings ファイルに移動します。

    download sub

    e. [インポート] をクリックします。

    import

  4. [ 発行プロファイルのインポート ] ダイアログ ボックスで、[ Windows Azure Web サイトからインポート] を選択し、ドロップダウン リストから Web サイトを選択し、[OK] をクリック します

    発行プロファイルのインポート

  5. [ 接続 ] タブで、[ 接続の検証 ] をクリックして、設定が正しいことを確認します。

    接続の検証

  6. 接続が検証されると、[接続の検証] ボタンの横に緑色のチェックマークが表示されます。 [次へ] をクリックします。

    正常に検証された接続

  7. [SchoolContext] の [リモート接続文字列] ドロップダウン リストを開き、作成したデータベースの接続文字列を選択します。

  8. [Code First Migrationsの実行 (アプリケーションの起動時に実行)] を選択します

  9. [UserContext (DefaultConnection)実行時にこの接続文字列を使用する] をオフにします。このアプリケーションではメンバーシップ データベースが使用されていないためです。

    Settings tab

  10. [次へ] をクリックします。

  11. [プレビュー] タブ 、[ プレビューの開始] をクリックします。

    [プレビュー] タブの [StartPreview] ボタン

    タブには、サーバーにコピーされるファイルの一覧が表示されます。 プレビューの表示は、アプリケーションを発行するために必要ありませんが、注意する必要がある便利な関数です。 この場合、表示されるファイルの一覧に対して何も行う必要はありません。 次にこのアプリケーションを展開するときに、変更されたファイルのみがこの一覧に表示されます。

    StartPreview ファイルの出力

  12. [発行] をクリックします。
    Visual Studio は、Windows Azure サーバーにファイルをコピーするプロセスを開始します。

  13. 出力 ウィンドウでは、実行されたデプロイ操作が表示され、デプロイが問題なく完了したことが報告されます。

    デプロイの成功を報告する出力ウィンドウ

  14. デプロイが成功すると、既定のブラウザーが展開された Web サイトの URL に自動的に開きます。
    これで、作成したアプリケーションはクラウドで実行されています。 [学生] タブをクリックします。

    Students_index_page_with_paging

この時点で、 [Code First Migrationsの実行 (アプリの起動時に実行)] を選択したため、SchoolContext データベースが Windows Azure SQL データベースに作成されました。 デプロイされた Web サイトの Web.config ファイルが変更され、 MigrateDatabaseToLatestVersion 初期化子は、コードがデータベース内のデータを初めて読み取りまたは書き込むときに実行されます ([ 学生 ] タブを選択したときに発生しました)。

[データベースを最新バージョンに移行する] が強調表示されているコードのスクリーンショット。

デプロイ プロセスでは、データベース スキーマの更新とデータベースのシード処理に使用するCode First Migrations用の新しい接続文字列 (SchoolContext_DatabasePublish) も作成されました。

接続文字列をDatabase_Publishする

DefaultConnection 接続文字列は、メンバーシップ データベース用です (このチュートリアルでは使用しません)。 SchoolContext 接続文字列は ContosoUniversity データベース用です。

Web.config ファイルの展開済みバージョンは、 ContosoUniversity\obj\Release\Package\PackageTmp\Web.configの自分 のコンピューターで確認できます。FTP を使用して、デプロイされた Web.config ファイル自体にアクセスできます。 手順については、「 Visual Studio を使用 ASP.NET Web 配置: コード更新プログラムをデプロイする」を参照してください。 「FTP ツールを使用するには、FTP URL、ユーザー名、パスワードの 3 つが必要です」で始まる手順に従います。

Note

Web アプリはセキュリティを実装していないため、URL を見つけたすべてのユーザーがデータを変更できます。 Web サイトをセキュリティで保護する方法については、「メンバーシップ、OAuth、SQL Databaseを使用してセキュリティで保護された ASP.NET MVC アプリを Windows Azure Web サイトにデプロイする」を参照してください。 Visual Studio の Windows Azure 管理ポータルまたはサーバー エクスプローラーを使用してサイトを停止することで、他のユーザーがサイトを使用できないようにすることができます。

[Windows Azure Web サイト] タブが展開され、その下に Con U が選択されていることを示すサーバー エクスプローラーのスクリーンショット。[Web サイトの停止] オプションが強調表示されているダイアログ メニュー。

コードの最初の初期化子

デプロイ セクションで、 MigrateDatabaseToLatestVersion 初期化子が使用されているのを確認しました。 また、Code First には、 CreateDatabaseIfNotExists (既定値)、 DropCreateDatabaseIfModelChangesDropCreateDatabaseAlways など、使用できる他の初期化子も用意されています。 初期化子は DropCreateAlways 、単体テストの条件を設定するのに役立ちます。 独自の初期化子を記述することもできます。また、アプリケーションがデータベースから読み取りまたはデータベースへの書き込みを行うまで待機しない場合は、初期化子を明示的に呼び出すことができます。 初期化子の包括的な説明については、 書籍「Programming Entity Framework: Code First by Julie Lerman and Rowan Miller」の第 6 章を参照してください。

まとめ

このチュートリアルでは、データ モデルを作成し、基本的な CRUD、並べ替え、フィルター処理、ページング、およびグループ化機能を実装する方法について説明しました。 次のチュートリアルでは、データ モデルを拡張することで、より高度なトピックを見始めます。

他の Entity Framework リソースへのリンクは、 ASP.NET データ アクセス コンテンツ マップにあります。