次の方法で共有


チュートリアル: MVC 5 を使う Entity Framework 6 Code First の概要

Note

新規開発の場合は、ASP.NET MVC コントローラーやビューよりも ASP.NET Core Razor Pages を使うことをお勧めします。 Razor Pages を使った、この内容に近いチュートリアル シリーズについては、「チュートリアル: ASP.NET Core の Razor Pages の概要」をご覧ください。 新しいチュートリアルは次のとおりです。

  • 使いやすい。
  • より多くの EF Core のベスト プラクティスが提供されている。
  • より効率的なクエリを使用している。
  • より最新の API を使用している。
  • 多くの機能をカバーしている。
  • 新しいアプリケーションの開発で推奨されるアプローチである。

このチュートリアル シリーズでは、データ アクセスに Entity Framework 6 を使う ASP.NET MVC 5 アプリケーションを構築する方法について説明します。 このチュートリアルでは、Code First ワークフローを使います。 Code First、Database First、Model First のどれを選ぶかについては、「モデルの作成」をご確認ください。

このチュートリアル シリーズでは、Contoso University サンプル アプリケーションをビルドする方法について説明します。 サンプル アプリケーションは、単純な、大学の Web サイトです。 ここでは、学生、コース、講師の情報を表示、更新できます。 作成する 2 つの画面を次に示します。

Students_Index_page

学生の編集

このチュートリアルでは、次の作業を行いました。

  • MVC Web アプリの作成
  • サイトのスタイルを設定する
  • Entity Framework 6 をインストールします
  • データ モデルを作成する
  • データベース コンテキストの作成
  • テスト データで DB を初期化する
  • LocalDB を使うように EF 6 を設定します
  • コントローラーとビューを作成する
  • データベースを表示する

前提条件

MVC Web アプリの作成

  1. Visual Studio を開き、ASP.NET Web アプリケーション (.NET Framework) テンプレートを使って C# Web プロジェクトを作成します。 プロジェクトに "ContosoUniversity" という名前を付けて、[OK] を選択します。

    Visual Studio の [新しいプロジェクト] ダイアログ ボックス

  2. 新しい ASP.NET Web アプリケーション "ContosoUniversity" で、[MVC] を選択します。

    Visual Studio の [新しい Web アプリ] ダイアログ ボックス

    Note

    既定では、[認証] オプションが [認証なし] に設定されています。 このチュートリアルでは、ユーザーは Web アプリにサインインする必要はありません。 また、サインインしているユーザーを基にアクセスが制限されることもありません。

  3. [OK] を選択すると、プロジェクトが作成されます。

サイトのスタイルを設定する

簡単な変更をいくつか行い、サイトのメニュー、レイアウト、ホーム ページを決めます。

  1. Views\Shared\_Layout.cshtml を開き、次の変更を行います。

    • 表示される "My ASP.NET アプリケーション" と "アプリケーション名" は、いずれも "Contoso University" に変更します。
    • "学生"、"コース"、"講師"、"学部" のメニュー エントリを追加し、"連絡先" エントリを削除します。

    変更箇所は、次のコード スニペットで強調表示されます。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>@ViewBag.Title - Contoso University</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="navbar-inner">
                <div class="container">
                    <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Contoso University", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                    <div class="nav-collapse collapse">
                        <ul class="nav">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Students", "Index", "Student")</li>
                            <li>@Html.ActionLink("Courses", "Index", "Course")</li>
                            <li>@Html.ActionLink("Instructors", "Index", "Instructor")</li>
                            <li>@Html.ActionLink("Departments", "Index", "Department")</li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    
        <div class="container">
            @RenderBody()
            <hr />
            <footer>
                <p>&copy; @DateTime.Now.Year - Contoso University</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
    
  2. Views\Home\Index.cshtml で、ファイルの内容を次のコードに置き換え、ASP.NET と MVC についてのテキストをこのアプリケーションについてのテキストに置き換えます。

    @{
        ViewBag.Title = "Home Page";
    }
    
    <div class="jumbotron">
        <h1>Contoso University</h1>
    </div>
    <div class="row">
        <div class="col-md-4">
            <h2>Welcome to Contoso University</h2>
            <p>Contoso University is a sample application that
            demonstrates how to use Entity Framework 6 in an 
            ASP.NET MVC 5 web application.</p>
        </div>
        <div class="col-md-4">
            <h2>Build it from scratch</h2>
            <p>You can build the application by following the steps in the tutorial series on the ASP.NET site.</p>
            <p><a class="btn btn-default" href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/">See the tutorial &raquo;</a></p>
        </div>
        <div class="col-md-4">
            <h2>Download it</h2>
            <p>You can download the completed project.</p>
            <p><a class="btn btn-default" href="https://webpifeed.blob.core.windows.net/webpifeed/Partners/ASP.NET%20MVC%20Application%20Using%20Entity%20Framework%20Code%20First.zip">Download &raquo;</a></p>
        </div>
    </div>
    
  3. Ctrl キーを押しながら F5 キーを押して、Web サイトを実行します。 メイン メニューが表示されたホーム ページが表示されます。

Entity Framework 6 のインストール

  1. [ツール] メニューで、[NuGet パッケージ マネージャー] を選択して、[パッケージ マネージャー コンソール] を選択します。

  2. [パッケージ マネージャー コンソール] ウィンドウで、次のコマンドを入力します。

    Install-Package EntityFramework
    

この手順は、このチュートリアルでユーザーが手動で行う手順の 1 つですが、ASP.NET MVC スキャフォールディング機能によって自動的に行われる場合があります。 Entity Framework (EF) を使う必要がある手順を確認できるように、手動で行います。 後でスキャフォールディングを使って、MVC コントローラーとビューを作成します。 別の方法としては、スキャフォールディングを行って、EF NuGet パッケージの自動インストール、データベース コンテキスト クラスの作成、接続文字列の作成を行うという方法があります。 そのような方法で行うことができる場合は、上記の手順をスキップして、エンティティ クラスの作成後に MVC コントローラーをスキャフォールディングするだけでかまいません。

データ モデルの作成

次に、Contoso University アプリケーションのエンティティ クラスを作成します。 次の 3 つのエンティティから始めます。

コース<->入学<->学生

エンティティ 関係
"コース" 対 "入学" 一対多
"学生" 対 "入学" 一対多

Student エンティティと Enrollment エンティティの間に一対多の関係があり、Course エンティティと Enrollment エンティティの間に一対多の関係があります。 言い換えると、1 人の学生をさまざまな講座に登録し、1 つの講座にたくさんの学生を登録できます。

以降のセクションでは、これらのエンティティごとにクラスを作成します。

Note

これらのエンティティ クラスの作成を完了する前にプロジェクトをコンパイルしようとすると、コンパイラ エラーが発生します。

Student エンティティ

  • Models フォルダーに "Student.cs" という名前のクラス ファイルを作成するには、ソリューション エクスプローラーで、そのフォルダーを右クリックし、[追加]>[クラス] を選択します。 テンプレート コードを次のコードに置き換えます。

    using System;
    using System.Collections.Generic;
    
    namespace ContosoUniversity.Models
    {
        public class Student
        {
            public int ID { get; set; }
            public string LastName { get; set; }
            public string FirstMidName { get; set; }
            public DateTime EnrollmentDate { get; set; }
            
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }
    

ID プロパティは、このクラスに相当するデータベース テーブルの主キー列になります。 既定では、Entity Framework は、 ID または classname ID という名前のプロパティを主キーとして解釈します。

Enrollments プロパティはナビゲーション プロパティです。 ナビゲーション プロパティには、このエンティティに関連する他のエンティティが含まれます。 この例では、Student エンティティの Enrollments プロパティに、その Student エンティティに関連するすべての Enrollment エンティティが保持されます。 つまり、データベース内の特定の Student 行に 関連する Enrollment 行 (StudentID 外部キー列にその学生の主キー値を含む行) が2 つある場合、その Student エンティティの Enrollments ナビゲーション プロパティには、その 2 つの Enrollment エンティティが含まれます。

ナビゲーション プロパティは、通常、"遅延読み込み" などの特定の Entity Framework 機能を利用できるように、virtual として定義されます。 (遅延読み込みについては、このシリーズで後出の関連データの読み取りに関するチュートリアルで後ほど説明します。)

ナビゲーション プロパティに複数のエンティティが含まれる場合 (多対多または一対多の関係で)、その型はリストにする必要があります。ICollection のように、エンティティを追加、削除、更新できるリストです。

Enrollment エンティティ

  • [Models] フォルダーで、Enrollment.cs を作成し、既存のコードを次のコードに変更します。

    namespace ContosoUniversity.Models
    {
        public enum Grade
        {
            A, B, C, D, F
        }
    
        public class Enrollment
        {
            public int EnrollmentID { get; set; }
            public int CourseID { get; set; }
            public int StudentID { get; set; }
            public Grade? Grade { get; set; }
            
            public virtual Course Course { get; set; }
            public virtual Student Student { get; set; }
        }
    }
    

EnrollmentID プロパティが主キーになります。このエンティティは、Student エンティティで見たように、単独でIDするのではなく、classname ID パターンを使用します。 通常、パターンを 1 つ選択し、データ モデル全体でそれを使用します。 ここのバリエーションから、いずれのパターンも利用できることがわかります。 後出のチュートリアルでは、classname なしで ID を使うとデータ モデル内で継承を実装しやすくなることについて説明します。

Grade プロパティは列挙型です。 Grade の型宣言の後の疑問符は、Grade プロパティが nullable であることを示します。 成績が null 値であることは、成績 0 とは異なります。null 値は成績がわからないか、まだ評価されていないことを意味します。

StudentID プロパティは外部キーです。それに対応するナビゲーション プロパティは Student です。 Enrollment エンティティは 1 つの Student エンティティに関連付けられており、1 つの Student エンティティだけを保持できます (先に見た、複数の Enrollment エンティティを保持できる Student.Enrollments ナビゲーション プロパティとは異なります)。

CourseID プロパティは外部キーです。それに対応するナビゲーション プロパティは Course です。 Enrollment エンティティは 1 つの Course エンティティに関連付けられます。

Entity Framework では、<navigation property name><primary key property name> (たとえば、Student ナビゲーション プロパティの場合、Student エンティティの主キーは ID であるため、StudentID) という名前のプロパティは、外部キー プロパティとして解釈されます。 また、外部キー プロパティにも、単純に <primary key property name> という名前を付けることができます (たとえば、Course エンティティの主キーは CourseID であるため、CourseID)。

Course エンティティ

  • Models フォルダーに、テンプレート コードを次のコードに置き換えて Course.cs を作成します。

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace ContosoUniversity.Models
    {
        public class Course
        {
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public int CourseID { get; set; }
            public string Title { get; set; }
            public int Credits { get; set; }
            
            public virtual ICollection<Enrollment> Enrollments { get; set; }
        }
    }
    

Enrollments プロパティはナビゲーション プロパティです。 1 つの Course エンティティにたくさんの Enrollment エンティティを関連付けることができます。

このシリーズで後出のチュートリアルでは、DatabaseGeneratedAttribute 属性について詳しく説明します。 基本的に、この属性によって、講座の主キーをデータベースに生成させず、自分で入力できるようになります。

データベース コンテキストの作成

所与のデータ モデルの Entity Framework 機能を調整するメイン クラスは、"データベース コンテキスト" クラスです。 このクラスは、System.Data.Entity.DbContext クラスから派生して作成します。 自分のコードに、データ モデルに含めるエンティティを指定します。 Entity Framework の特定の動作をカスタマイズすることもできます。 このプロジェクトでは、クラスに SchoolContext という名前が付けられています。

  • ContosoUniversity プロジェクトにフォルダーを作成するには、ソリューション エクスプローラーでプロジェクトを右クリックし、[追加] をクリックして、[新しいフォルダー] をクリックします。 新しいフォルダーに "DAL" (データ アクセス層の略) という名前を付けます。 そのフォルダーに、"SchoolContext.cs" という名前の新しいクラス ファイルを作成して、テンプレート コードを次のコードに置き換えます。

    using ContosoUniversity.Models;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    
    namespace ContosoUniversity.DAL
    {
        public class SchoolContext : DbContext
        {
        
            public SchoolContext() : base("SchoolContext")
            {
            }
            
            public DbSet<Student> Students { get; set; }
            public DbSet<Enrollment> Enrollments { get; set; }
            public DbSet<Course> Courses { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
        }
    }
    

エンティティ セットを指定する

このコードでは、エンティティ セットごとに DbSet プロパティを作成します。 Entity Framework の用語では、"エンティティ セット" は通常はデータベース テーブルに対応し、"エンティティ" はテーブルの行に対応します。

Note

DbSet<Enrollment> ステートメントと DbSet<Course> ステートメントを省略しても、動作は同じです。 Entity Framework にはこれらが暗黙的に含まれることがあります。これは、Student エンティティが Enrollment エンティティを参照し、Enrollment エンティティが Course エンティティを参照するためです。

接続文字列を指定する

接続文字列の名前 (後で Web.config ファイルに追加します) がコンストラクターに渡されます。

public SchoolContext() : base("SchoolContext")
{
}

Web.config ファイルに格納されている接続文字列の名前ではなく、接続文字列自体を渡すこともできます。 使用するデータベースを指定するためのオプションに関する詳細については、「接続文字列とモデル」をご覧ください。

接続文字列または接続文字列の名前を明示的に指定しない場合、Entity Framework では、接続文字列名がクラス名と同じであると見なされます。 ここで、この例の既定の接続文字列名は SchoolContext となり、明示的に指定するものと同じになります。

単数形のテーブル名を指定する

OnModelCreating メソッドの modelBuilder.Conventions.Remove ステートメントを使用すると、テーブル名が複数形化されなくなります。 これを行わなかった場合、データベースに生成されるテーブルは、StudentsCoursesEnrollments という名前になります。 その代わりに、テーブル名は StudentCourse、および Enrollment になります。 テーブル名を複数形にするかどうかについては、開発者の間で意見が分かれるでしょう。 このチュートリアルでは単数形を使用しますが、重要な点は、このコード行を含めたり省略したりして、任意のフォームを選択できることです。

テスト データで DB を初期化する

Entity Framework では、アプリケーションの実行時にデータベースを自動的に作成 (または削除して再作成) できます。 これをアプリケーションが実行されるたびに行うか、モデルが既存のデータベースと同期していない場合にのみ行うかを指定できます。 また、テスト データを設定するには、データベースの作成後に Entity Framework が自動的に呼び出す Seed メソッドを記述することもできます。

既定の動作は、データベースが存在しない場合にのみデータベースを作成する (および、モデルが変更されているとともにデータベースが既に存在している場合は例外をスローする) というものです。 このセクションでは、モデルが変更されるたびにデータベースが削除されて再作成されるように指定します。 データベースが削除されると、すべてのデータが失われます。 一般的に、開発中であればこれは問題ありません。Seed メソッドはデータベースが再作成されると実行され、このメソッドによってテスト データが再作成されるからです。 ただし、運用環境では通常、データベース スキーマを変更する必要があるたびにすべてのデータを失うようなことはしたくありません。 データベースを削除して再作成するのではなく、Code First Migrations を使ってデータベース スキーマを変更することでモデルの変更を処理する方法について、後ほど説明します。

  1. DAL フォルダーに "SchoolInitializer.cs" という名前の新しいクラス ファイルを作成し、テンプレート コードを次のコードに置き換えます。これにより、必要に応じてデータベースが作成され、テスト データが新しいデータベースに読み込まれます。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;
    using ContosoUniversity.Models;
    
    namespace ContosoUniversity.DAL
    {
        public class SchoolInitializer : System.Data.Entity. DropCreateDatabaseIfModelChanges<SchoolContext>
        {
            protected override void Seed(SchoolContext context)
            {
                var students = new List<Student>
                {
                new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
                new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
                new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
                new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
                new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
                new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
                new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
                new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
                };
    
                students.ForEach(s => context.Students.Add(s));
                context.SaveChanges();
                var courses = new List<Course>
                {
                new Course{CourseID=1050,Title="Chemistry",Credits=3,},
                new Course{CourseID=4022,Title="Microeconomics",Credits=3,},
                new Course{CourseID=4041,Title="Macroeconomics",Credits=3,},
                new Course{CourseID=1045,Title="Calculus",Credits=4,},
                new Course{CourseID=3141,Title="Trigonometry",Credits=4,},
                new Course{CourseID=2021,Title="Composition",Credits=3,},
                new Course{CourseID=2042,Title="Literature",Credits=4,}
                };
                courses.ForEach(s => context.Courses.Add(s));
                context.SaveChanges();
                var enrollments = new List<Enrollment>
                {
                new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
                new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
                new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
                new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
                new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
                new Enrollment{StudentID=3,CourseID=1050},
                new Enrollment{StudentID=4,CourseID=1050,},
                new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
                new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
                new Enrollment{StudentID=6,CourseID=1045},
                new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
                };
                enrollments.ForEach(s => context.Enrollments.Add(s));
                context.SaveChanges();
            }
        }
    }
    

    Seed メソッドでは、データベース コンテキスト オブジェクトを入力パラメータとして受け取ります。また、メソッド内のコードによって、そのオブジェクトを使って新しいエンティティがデータベースに追加されます。 エンティティの種類ごとに、コードによって新しいエンティティのコレクションが作成され、適切な DbSet プロパティに追加された後、変更がデータベースに保存されます。 ここで行われているように、エンティティの各グループの後に SaveChanges メソッドを呼び出す必要はありませんが、これを行うと、コードによってデータベースへの書き込みが行われている間に例外が発生した場合に問題の原因を特定しやすくなります。

  2. 初期化子クラスを使うように Entity Framework に指示するには、次の例に示すように、アプリケーションの Web.config ファイル (ルート プロジェクト フォルダー内のもの) 内にある entityFramework 要素に要素を追加します。

    <entityFramework>
      <contexts>
        <context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
          <databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
        </context>
      </contexts>
      <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
        <parameters>
          <parameter value="v11.0" />
        </parameters>
      </defaultConnectionFactory>
      <providers>
        <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      </providers>
    </entityFramework>
    

    context type によって、完全修飾コンテキスト クラス名と、それが含まれるアセンブリが指定されます。また、databaseinitializer type によって、初期化子クラスの完全修飾名と、それが含まれるアセンブリが指定されます。 (EF で初期化子を使う必要がない場合は、context 要素に disableDatabaseInitialization="true" 属性を設定できます。)詳細については、「構成ファイルの設定」をご覧ください。

    初期化子を Web.config ファイルに設定するもう 1 つの方法として、Global.asax.cs ファイルで Database.SetInitializer ステートメントを Application_Start メソッドに追加してこれをコード内で行うという方法があります。 詳細については、「Entity Framework Code First でのデータベース初期化子について」をご覧ください。

これで、アプリケーションが設定されました。アプリケーションの特定の実行でデータベースに初めてアクセスしたときに、Entity Framework によるデータベースとモデル (SchoolContext とエンティティ クラス) の比較が行われます。 相違がある場合、アプリケーションでは、データベースの削除と再作成が行われます。

Note

運用 Web サーバーにアプリケーションをデプロイする場合は、データベースを削除して再作成するコードを削除または無効にする必要があります。 これは、このシリーズで後出のチュートリアルで行います。

LocalDB を使うように EF 6 を設定する

LocalDB は、SQL Server Express データベース エンジンの軽量バージョンです。 インストールと構成、オンデマンドでの開始、ユーザー モードでの実行が簡単です。 LocalDB は SQL Server Express の特別な実行モードで実行され、データベースを .mdf ファイルとして操作できます。 LocalDB データベース ファイルは、プロジェクトを含むデータベースをコピーする必要がある場合に、Web プロジェクトの App_Data フォルダーに配置できます。 SQL Server Express のユーザー インスタンス機能を使用して .mdf ファイルを操作することもできますが、ユーザー インスタンス機能は非推奨です。そのため、.mdf ファイルを操作する場合は LocalDB をお勧めします。 LocalDB は、既定で、Visual Studio を使ってインストールされます。

通常、SQL Server Express は、運用環境の Web アプリケーションには使いません。 特に LocalDB は、IIS で動作するように設計されていないため、Web アプリケーションでの運用目的の使用はお勧めしません。

  • このチュートリアルでは、LocalDB を使います。 アプリケーションの Web.config ファイルを開き、次の例で示しているように、connectionStrings 要素を appSettings 要素の前に追加します。 (ルート プロジェクト フォルダー内の Web.config ファイルを必ず更新してください。また、Views サブフォルダーには、Web.config ファイルもありますが、これは更新の必要がありません。)

    <connectionStrings>
        <add name="SchoolContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
    </connectionStrings>
    <appSettings>
      <add key="webpages:Version" value="3.0.0.0" />
      <add key="webpages:Enabled" value="false" />
      <add key="ClientValidationEnabled" value="true" />
      <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    </appSettings>
    

追加した接続文字列では、Entity Framework で "ContosoUniversity1.mdf" という名前の LocalDB データベースを使うように指定しています。 (このデータベースはまだ存在していませんが、EF によって作成されます。)App_Data フォルダーにこのデータベースを作成する場合は、接続文字列に AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf を追加できます。 接続文字列の詳細については、「ASP.NET Web アプリケーションでの SQL Server 接続文字列」をご覧ください。

実際には、Web.config ファイルに接続文字列は必要ありません。 接続文字列を指定しない場合、Entity Framework では、コンテキスト クラスに基づく既定の接続文字列が使用されます。 詳細については、「新しいデータベースの Code First」をご覧ください。

コントローラーとビューを作成する

次に、データを表示する Web ページを作成します。 データを要求するプロセスによって、データベースの作成が自動的にトリガーされます。 まずは、新しいコントローラーを作成します。 ただし、その前に、プロジェクトをビルドして、モデル クラスとコンテキスト クラスが MVC コントローラー スキャフォールディングで使えるようにします。

  1. ソリューション エクスプローラーにある Controllers フォルダーを右クリックして、[追加] を選択して、[新規スキャフォールディング アイテム] をクリックします。

  2. [スキャフォールディングの追加] ダイアログ ボックスで、[Entity Framework を使用した、ビューがある MVC 5 コントローラー] を選択して、[追加] を選択します。

    Visual Studio の [スキャフォールディングの追加] ダイアログ

  3. [コントローラーの追加] ダイアログ ボックスで、次の選択を行って、[追加] を選択します。

    • モデル クラス: Student (ContosoUniversity.Models)。 (ドロップダウン リストにこのオプションが表示されない場合は、プロジェクトをビルドしてやり直してください)。

    • データ コンテキスト クラス: SchoolContext (ContosoUniversity.DAL)

    • コントローラー名: StudentController (StudentsController ではありません)。

    • 他のフィールドは既定値のままにします。

      [追加] をクリックすると、スキャフォールディングによって StudentsController.cs ファイルと、コントローラーと連動する一連のビュー (.cshtml ファイル) が作成されます。 その後、Entity Framework を使うプロジェクトを作成する場合は、スキャフォールディングの他の機能も利用できます。最初のモデル クラスを作成して、接続文字列は作成せずに、[コントローラーの追加] ボックスで、[データ コンテキスト クラス] の横にある + ボタンを選択して、新しいデータ コンテキストを指定します。 スキャフォールディングによって、DbContext クラスと接続文字列に加え、コントローラーとビューが作成されます。

  4. Visual Studio で Controllers\StudentController.cs ファイルが 開きます。 データベース コンテキスト オブジェクトをインスタンス化するクラス変数が作成されていることがわかります。

    private SchoolContext db = new SchoolContext();
    

    Index アクション メソッドは、データベース コンテキスト インスタンスの Students プロパティを読み取ることによって、Students エンティティ セットから学生の一覧を取得します。

    public ViewResult Index()
    {
        return View(db.Students.ToList());
    }
    

    Students/Index.cshtml ビューでは、この一覧が表形式で表示されます。

    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.LastName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstMidName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </th>
            <th></th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.LastName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FirstMidName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentDate)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ID })
            </td>
        </tr>
    }
    
  5. Ctrl キーを押しながら F5 キーを押してプロジェクトを実行します。 ("シャドウ コピーを作成できません" というエラーが表示された場合は、ブラウザーを閉じてからやり直してください。)

    [Students] タブをクリックすると、Seed メソッドによって挿入されたテスト データが表示されます。 ブラウザー ウィンドウの幅に応じて、上部のアドレス バーに [学生] タブ リンクが表示されます。表示されない場合は、右上隅をクリックして、リンクを表示する必要があります。

    Menu ボタン

データベースを表示する

ユーザーが [学生] ページを実行し、アプリケーションによってデータベースへのアクセスが試みられると、EF では、データベースが存在していないことが検出され、データベースが作成されました。 その後、EF によってシード メソッドが実行されて、データベースにデータが設定されました。

サーバー エクスプローラーまたは SQL Server オブジェクト エクスプローラー (SSOX) を 使用して、Visual Studio でデータベースを表示できます。 このチュートリアルでは、サーバー エクスプローラーを使います。

  1. ブラウザーを閉じます。

  2. サーバー エクスプローラーで、[データ接続] を展開し (最初に [更新] ボタンの選択が必要な場合があります)、[学校コンテキスト (ContosoUniversity)] を展開し、[テーブル] を展開して、新しいデータベースにテーブルを表示します。

  3. [Student] テーブルを右クリックし、[テーブル データの表示] をクリックすると、作成された列とテーブルに挿入された行が表示されます。

  4. サーバー エクスプローラーの接続を終了します。

ContosoUniversity1.mdf データベース ファイルと .ldf データベース ファイルが %USERPROFILE% フォルダーに作成されています。

DropCreateDatabaseIfModelChanges 初期化子を使っているため、Student クラスに変更を加えることができるようになり、もう一度アプリケーションを実行すると、その変更に合わせてデータベースが自動的に再作成されます。 たとえば、Student クラスに EmailAddress プロパティを追加する場合は、[学生] ページをもう一度実行して、テーブルを再び確認すると、新しい EmailAddress 列が表示されるようになります。

規約

Entity Framework で完全なデータベースの作成が可能となるように記述しなくてはならないコードの量は、"規約" により、または Entity Framework での想定により、最小限に抑えられます。 その中には、既に着目されていたか、ユーザーが気づかないうちに使用されていたものもあります。

  • テーブル名にはエンティティ クラス名の複数形が使用されます。
  • 列名には、エンティティ プロパティ名が使用されます。
  • ID または classname ID という名前のエンティティ プロパティは、主キー プロパティとして認識されます。
  • <ナビゲーション プロパティ名><主キー プロパティ名> という名前 (たとえば、Student ナビゲーション プロパティの場合、Student エンティティの主キーが ID なので、StudentID となります) が付いている場合、プロパティは外部キー プロパティとして解釈されます。 また、外部キー プロパティにも、単純に <primary key property name> という名前を付けることができます (たとえば、Enrollment エンティティの主キーは EnrollmentID であるため、EnrollmentID)。

規約をオーバーライドできることを確認しました。 たとえば、テーブル名を複数形化しないように指定して、後でプロパティを外部キー プロパティとして明示的にマークする方法を確認します。

コードを取得する

完成したプロジェクトのダウンロード

その他のリソース

EF 6 の詳細については、次の記事をご覧ください。

次のステップ

このチュートリアルでは、次の作業を行いました。

  • MVC Web アプリを作成しました
  • サイトのスタイルを設定する
  • Entity Framework 6 をインストールしました
  • データ モデルを作成した
  • データベース コンテキストを作成した
  • テスト データで DB を初期化した
  • LocalDB を使うように EF 6 を設定しました
  • コントローラーとビューを作成した
  • データベースを表示した

コントローラーとビューでのコードの作成、読み取り、更新、削除 (CRUD) コードを確認してカスタマイズする方法については、次の記事に進んでください。