ASP.NET MVC アプリケーションでの Entity Framework での並べ替え、フィルター処理、ページング (3/10)
Contoso University サンプル Web アプリケーションでは、Entity Framework 5 Code First と Visual Studio 2012 を使用して、ASP.NET MVC 4 アプリケーションを作成する方法を示します。 チュートリアル シリーズについては、シリーズの最初のチュートリアルをご覧ください。
Note
解決できない問題が発生した場合は、 完了した章をダウンロード して、問題を再現してみてください。 一般に、コードを完成したコードと比較することで、問題の解決策を見つけることができます。 一般的なエラーとその解決方法については、「エラーと回避策」を参照してください。
前のチュートリアルでは、エンティティの基本的な CRUD 操作用の一連の Web ページを Student
実装しました。 このチュートリアルでは、[ 学生 のインデックス] ページに並べ替え、フィルター処理、ページング機能を追加します。 単純なグループ化を実行するページも作成します。
次の図は、作業が終了したときにページがどのように表示されるかを示しています。 列見出しとは、ユーザーがクリックしてその列で並べ替えを行うことができるリンクです。 列見出しを繰り返しクリックすると、昇順と降順の並べ替え順序が切り替えられます。
Students インデックス ページに列の並べ替えリンクを追加する
学生インデックス ページに並べ替えを追加するには、コントローラーの メソッドを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
変更し、 ステートメントの後に メソッドをToList
switch
呼び出します。 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
使用して、適切なクエリ文字列値を含むハイパーリンクを設定します。
ページを実行し、[姓] 列と [登録日] 列見出しをクリックして、並べ替えが機能することを確認します。
[姓] 見出しをクリックすると、学生は姓の降順で表示されます。
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>
ページを実行し、検索文字列を入力し、[ 検索 ] をクリックしてフィルター処理が機能していることを確認します。
URL に "an" 検索文字列が含まれていないことに注意してください。つまり、このページをブックマークすると、ブックマークを使用してもフィルター処理された一覧は取得されません。 チュートリアルの後半でフィルター条件にクエリ文字列を使用するように [ 検索 ] ボタンを変更します。
学生のインデックス ページにページングを追加する
Students Index ページにページングを追加するには、まず PagedList.Mvc NuGet パッケージをインストールします。 次に、 メソッドに追加の変更を Index
加え、ページング リンクをビューに Index
追加します。 PagedList.Mvc は、ASP.NET MVC 用の多くの優れたページングおよび並べ替えパッケージの 1 つであり、ここでの使用は、他のオプションに対する推奨事項としてではなく、例としてのみ意図されています。 次の図は、ページング リンクを示しています。
PagedList.MVC NuGet パッケージをインストールする
NuGet PagedList.Mvc パッケージは、 PagedList パッケージを依存関係として自動的にインストールします。 PagedList パッケージは、 および コレクションのPagedList
コレクション型と拡張メソッドをIQueryable
IEnumerable
インストールします。 拡張メソッドは、 または IEnumerable
からコレクション内に PagedList
1 ページのデータをIQueryable
作成し、PagedList
コレクションにはページングを容易にするプロパティとメソッドがいくつか用意されています。 PagedList.Mvc パッケージは、ページング ボタンを表示するページング ヘルパーをインストールします。
[ツール] メニューの [NuGet パッケージ マネージャー] を選択し、[ソリューションの NuGet パッケージの管理] を選択します。
[ NuGet パッケージの管理 ] ダイアログ ボックスで、左側の [ オンライン ] タブをクリックし、検索ボックスに「paged」と入力します。 PagedList.Mvc パッケージが表示されたら、[インストール] をクリックします。
[ プロジェクトの選択 ] ボックスで、[ 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.PageNumber
、 Model.PageCount
ページ数がページ数より大きくなります)。
ページング ボタンは、ヘルパーによって PagedListPager
表示されます。
@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )
ヘルパーには PagedListPager
、URL やスタイル設定など、カスタマイズできるさまざまなオプションが用意されています。 詳細については、GitHub サイト の TroyGoode/PagedList を参照してください。
ページを実行します。
異なる並べ替え順でページングのリンクをクリックし、ページングが機能することを確認します。 その後で、検索文字列を入力して、ページングをもう一度試し、並べ替えとフィルター処理を使用してもページングが正しく機能することを確認します。
学生の統計情報を表示する 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>
アプリを実行し、[ バージョン情報 ] リンクをクリックします。 登録の日付ごとの学生の数が、テーブルに表示されます。
省略可能: アプリを 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で動作します。
Windows Azure 管理ポータルで、左側のタブで [Web サイト] をクリックし、[新規] をクリックします。
[ カスタム作成] をクリックします。
[新しい Web サイト - カスタム作成] ウィザードが開きます。
ウィザードの [新しい Web サイト ] ステップで、[ URL ] ボックスに、アプリケーションの一意の URL として使用する文字列を入力します。 ここに入力した文字列と、このテキスト ボックスの右側に表示されている文字列を組み合わせたものが実際の URL になります。 この図は "ConU" を示していますが、その URL はおそらく取得されるため、別の URL を選択する必要があります。
[ リージョン ] ドロップダウン リストで、近くのリージョンを選択します。 この設定では、Web サイトを実行するデータ センターを指定します。
[ データベース ] ドロップダウン リストで、[ Create a free 20 MB SQL database]\(無料の 20 MB SQL データベースの作成\) を選択します。
[ DB 接続文字列名] に「 SchoolContext」と入力します。
ボックスの下部にある右を指す矢印をクリックします。 ウィザードが [ データベース設定] ステップに進みます。
[ 名前 ] ボックスに「 ContosoUniversityDB」と入力します。
[サーバー] ボックスで、[新しいSQL Database サーバー] を選択します。 または、以前にサーバーを作成した場合は、ドロップダウン リストからそのサーバーを選択できます。
管理者の ログイン名 とパスワードを入力 します。 [新しい SQL Database サーバー] を選択した場合は、既存の名前とパスワードではなく、このデータベースへのアクセス時に使用する新しい名前とパスワードを入力してください。 前に作成したサーバーを選択した場合は、そのサーバーの資格情報を入力します。 このチュートリアルでは、[高度なチェック] ボックスは選択しません。 [詳細設定] オプションを使用すると、データベースの照合順序を設定できます。
Web サイトに対して選択したのと同じ リージョン を選択します。
ボックスの右下にあるチェックマークをクリックして、完了したことを示します。
次の図は、既存のSQL Serverとログインの使用を示しています。
管理ポータルが [Web サイト] ページに戻り、[ 状態] 列にサイトが作成されていることを示します。 しばらくすると (通常は 1 分未満)、[ 状態] 列にサイトが正常に作成されたことが表示されます。 左側のナビゲーション バーで、アカウント内のサイトの数が [Web サイト ] アイコンの横に表示され、[ SQL データベース ] アイコンの横にデータベースの数が表示されます。
アプリケーションを Windows Azure にデプロイする
Visual Studio のソリューション エクスプローラーで、プロジェクトを右クリックし、コンテキスト メニューの [発行] をクリックします。
Web 発行ウィザードの [プロファイル] タブで、[インポート] をクリックします。
Visual Studio で Windows Azure サブスクリプションを以前に追加していない場合は、次の手順を実行します。 これらの手順では、サブスクリプションを追加して、[ Windows Azure Web サイトからインポート ] のドロップダウン リストに Web サイトが含まれるようにします。
a. [ 発行プロファイルのインポート ] ダイアログ ボックスで、[ Windows Azure Web サイトからのインポート] をクリックし、[ Windows Azure サブスクリプションの追加] をクリックします。
b. [ Windows Azure サブスクリプションのインポート ] ダイアログ ボックスで、[ サブスクリプション ファイルのダウンロード] をクリックします。
c. ブラウザー ウィンドウで、 .publishsettings ファイルを 保存します。
警告
セキュリティ - publishsettings ファイルには、Windows Azure サブスクリプションとサービスの管理に使用される資格情報 (エンコードされていない) が含まれています。 このファイルのセキュリティのベスト プラクティスは、ソース ディレクトリの外部 ( Libraries\Documents フォルダーなど) に一時的に保存し、インポートが完了したら削除することです。 ファイルにアクセスできる悪意のあるユーザーは
.publishsettings
、Windows Azure サービスを編集、作成、削除できます。d. [ Windows Azure サブスクリプションのインポート ] ダイアログ ボックスで、[ 参照 ] をクリックし、 .publishsettings ファイルに移動します。
e. [インポート] をクリックします。
[ 発行プロファイルのインポート ] ダイアログ ボックスで、[ Windows Azure Web サイトからインポート] を選択し、ドロップダウン リストから Web サイトを選択し、[OK] をクリック します。
[ 接続 ] タブで、[ 接続の検証 ] をクリックして、設定が正しいことを確認します。
接続が検証されると、[接続の検証] ボタンの横に緑色のチェックマークが表示されます。 [次へ] をクリックします。
[SchoolContext] の [リモート接続文字列] ドロップダウン リストを開き、作成したデータベースの接続文字列を選択します。
[Code First Migrationsの実行 (アプリケーションの起動時に実行)] を選択します。
[UserContext (DefaultConnection) の実行時にこの接続文字列を使用する] をオフにします。このアプリケーションではメンバーシップ データベースが使用されていないためです。
[次へ] をクリックします。
[プレビュー] タブ で 、[ プレビューの開始] をクリックします。
タブには、サーバーにコピーされるファイルの一覧が表示されます。 プレビューの表示は、アプリケーションを発行するために必要ありませんが、注意する必要がある便利な関数です。 この場合、表示されるファイルの一覧に対して何も行う必要はありません。 次にこのアプリケーションを展開するときに、変更されたファイルのみがこの一覧に表示されます。
[発行] をクリックします。
Visual Studio は、Windows Azure サーバーにファイルをコピーするプロセスを開始します。出力 ウィンドウでは、実行されたデプロイ操作が表示され、デプロイが問題なく完了したことが報告されます。
デプロイが成功すると、既定のブラウザーが展開された Web サイトの URL に自動的に開きます。
これで、作成したアプリケーションはクラウドで実行されています。 [学生] タブをクリックします。
この時点で、 [Code First Migrationsの実行 (アプリの起動時に実行)] を選択したため、SchoolContext データベースが Windows Azure SQL データベースに作成されました。 デプロイされた Web サイトの Web.config ファイルが変更され、 MigrateDatabaseToLatestVersion 初期化子は、コードがデータベース内のデータを初めて読み取りまたは書き込むときに実行されます ([ 学生 ] タブを選択したときに発生しました)。
デプロイ プロセスでは、データベース スキーマの更新とデータベースのシード処理に使用するCode First Migrations用の新しい接続文字列 (SchoolContext_DatabasePublish) も作成されました。
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 管理ポータルまたはサーバー エクスプローラーを使用してサイトを停止することで、他のユーザーがサイトを使用できないようにすることができます。
コードの最初の初期化子
デプロイ セクションで、 MigrateDatabaseToLatestVersion 初期化子が使用されているのを確認しました。 また、Code First には、 CreateDatabaseIfNotExists (既定値)、 DropCreateDatabaseIfModelChanges 、 DropCreateDatabaseAlways など、使用できる他の初期化子も用意されています。 初期化子は DropCreateAlways
、単体テストの条件を設定するのに役立ちます。 独自の初期化子を記述することもできます。また、アプリケーションがデータベースから読み取りまたはデータベースへの書き込みを行うまで待機しない場合は、初期化子を明示的に呼び出すことができます。 初期化子の包括的な説明については、 書籍「Programming Entity Framework: Code First by Julie Lerman and Rowan Miller」の第 6 章を参照してください。
まとめ
このチュートリアルでは、データ モデルを作成し、基本的な CRUD、並べ替え、フィルター処理、ページング、およびグループ化機能を実装する方法について説明しました。 次のチュートリアルでは、データ モデルを拡張することで、より高度なトピックを見始めます。
他の Entity Framework リソースへのリンクは、 ASP.NET データ アクセス コンテンツ マップにあります。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示