トレーニングコース。 ASP.NET MVCアプリケーションのEntity Frameworkデータモデルの作成

Contoso UniversityのWebアプリケーションを例に使用して、Entity Frameworkを使用したASP.NET MVCアプリケーションの作成を示します。これには、学生の受講、コースの作成、教師の任命などの機能が含まれます。



これらのチュートリアルでは、Contoso UniversityのWebアプリケーションを構築するプロセスを順を追って説明します。 完成したアプリケーションをダウンロードするか、指定された一連の手順に従って作成できます。 例はC#で提供され、コード例はC#およびVBで利用可能です。 トレーニング資料に間接的に関連する質問がある場合は、 ASP.NET Entity FrameworkフォーラムまたはEntity Framework and LINQ to Entitiesフォーラムに質問できます。



学習には、Visual StudioでASP.NET MVCを操作する知識が必要です。それ以外の場合は、 ASP.NET MVCチュートリアルの学習を開始するのに適した場所です。 ASP.NET Webフォームを使用する場合は、「Entity Framework入門」および「Entity Frameworkの 継続」をご覧ください



開始する前に、次のソフトウェアがインストールされていることを確認してください。



コントーソ大学



開発しているアプリケーションは、単純な大学のWebサイトです。



clip_image001



ユーザーは、学生、コース、教師に関するデータを表示および更新できます。 以下に起こることのいくつかのスクリーンショット。



clip_image002



clip_image003



clip_image004



UIはデフォルトのテンプレートで生成されるものとスタイルが似ているため、Entity Frameworkの使用に関する問題に焦点が当てられます。



Entity Frameworkを使用した開発アプローチ



この図に基づいて、Entity Frameworkでデータを操作するための3つのアプローチがあります: Database FirstModel First 、およびCode Firstです。



clip_image005



最初のデータベース


既存のデータベースの場合、Entity Frameworkは、データベースオブジェクト(テーブルや列など)に対応するクラスとプロパティで構成されるデータモデルを自動的に作成できます。 データベース構造(ストアスキーマ)、データモデル( 概念モデル )、およびそれらの相互のマッピングに関する情報は、 .edmxファイルのXMLに含まれてます。 Visual Studioは、 .edmxを表示および編集できるEntity Frameworkグラフィックデザイナーを提供します。 Entity Framework入門とWeb FormsマテリアルのEntity Frameworkパーツの継続では、Database Firstアプローチを使用します。



最初のモデル


データベースがない場合は、Entity Framework Visual Studioデザイナーを使用してデータモデルを作成することから開始できます。 モデルの作業を終えた後、デザイナーはDDL( データ 定義 言語 )コードを生成してデータベースを作成します。 このアプローチでは、モデルとマッピング情報を保存するために.edmxも使用されますEntity Framework 4の新機能には、このアプローチを使用した小さな開発例が含まれています。



コードファースト


データベースの可用性に関係なく、データベース内のエンティティに対応するクラスとプロパティのコードを手動で記述し、ファイルを使用せずにEntity Frameworkでこのコードを使用できます edmx 。 そのため、公式の名前はCode Firstですが、このアプローチがコード のみと呼ばれる方法を見ることができます。 コードで表されるストアスキーマと概念モデル間のマッピングは、慣例および特別なマッピングAPIによって処理されます。 データベースがまだ存在しない場合、Entity Frameworkは、モデルが変更された場合にデータベースを作成、削除、または再作成できます。



Code First用に開発されたデータアクセスAPIは、 DbContext



クラスに基づいています。 APIは、開発時にDatabase FirstアプローチおよびModel Firstアプローチを使用することもできます。 「 コードファーストがコードファーストではない場合 」を参照してください Entity Framework開発チームのブログ。



POCO(プレーンオールドCLRオブジェクト)



デフォルトでは、データベースファーストおよびモデルファーストアプローチの場合、データモデルクラスはEntityObjectから継承し、Entity Framework機能を提供します。 これは、これらのクラスが永続的に無知ではないため、 ドメイン駆動設計の条件の1つに完全に準拠していないことを意味します 。 Entity Frameworkを使用したすべての開発アプローチは、POCO( プレーンな 古い CLR オブジェクト )でも機能します 。これは、一般に、 EntityObject



の継承がないために永続性を無視することを意味します。



MVC Webアプリケーションの作成



Visual Studioを開き、 ASP.NET MVC 3 Webアプリケーションを使用して新しい「ContosoUniversity」プロジェクトを作成します



clip_image006



新しい ASPで。 NET MVC 3 プロジェクトでインターネット アプリケーションテンプレートとRazorビューエンジンを選択し、[ ユニット テスト プロジェクトの 作成 ]チェックボックスをオフにして[ OK ]をクリックします。



clip_image007



スタイルのカスタマイズ


いくつかの小さな修正により、サイトのメニュー、アイテムのレイアウト、およびホームページが変更されます。



Contoso Universityメニューをカスタマイズするには、 Views \ Shared \ _ Layoutで。 例のように、 cshtmlh



1



のテキストとメニューのリンクを置き換えます。



 <!DOCTYPE html> <html> <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> </head> <body> <div class="page"> <div id="header"> <div id="title"> <h1>Contoso University</h1> </div> <div id="logindisplay"> @Html.Partial("_LogOnPartial") </div> <div id="menucontainer"> <ul id="menu"> <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 id="main"> @RenderBody() </div> <div id="footer"> </div> </div> </body> </html>
      
      





Views \ Home \ Index.cshtmlで、 h2



タグのすべてを削除します。



Controllers \ HomeController.csで 、「ASP.NET MVCへようこそ!」を置き換えます。 「Contoso Universityへようこそ!」



コンテンツ\ サイト内。 cssでメニューを左に移動すると、次の変更が行われます。



 #main { clear: both; padding: 30px 30px 15px 30px; background-color: #fff; border-radius: 4px 0 0 0; -webkit-border-radius: 4px 0 0 0; -moz-border-radius: 4px 0 0 0; }
      
      





 nav, #menucontainer { margin-top: 40px; clear: both; float: left; }
      
      





プロジェクトを実行します。



clip_image001 [1]



データモデルの作成



次に、Contoso Universityの最初のエンティティクラスを作成します。 次の3つのエンティティから始めます。



clip_image008



Student



Enrollment



エンティティの間に1 Enrollment



関係が確立され、 Course



Enrollment



間に1 Enrollment



関係が確立されています。 つまり、学生は任意の数のコースに参加でき、コースには任意の数の学生が参加できます。



将来的には、これらのエンティティごとにクラスを作成します。



注:これらのエンティティのクラスを作成せずにプロジェクトをコンパイルすると、コンパイラエラーが発生します。



エッセンス学生


clip_image009



Modelsフォルダーで、 Studentを作成します csおよび生成されたコードを次のように置き換えます。



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





StudentID



プロパティは、対応するテーブルの主キーになります。 既定では、Entity FrameworkはID



またはクラス名 ID



を持つプロパティを主キーとして扱います。



Enrollments



プロパティ- ナビゲーションプロパティ 。 ナビゲーションプロパティには、現在に関連する他のエンティティが含まれます。 この場合、 Enrollments



プロパティには、現在のStudent



エンティティに関連付けられているすべてのEnrollment



エンティティが含まれます。 つまり、データベース内の特定のStudent



レコードが2つのEnrollment



レコード( StudentID



外部キーStudentID



学生のプライマリキー値を含むレコード)に関連付けられている場合、このEnrollments



レコードのプロパティには2つのEnrollment



エンティティが含まれます。



通常、ナビゲーションプロパティは、 遅延 読み込みと呼ばれるEntity Framework機能を使用するために、 virtual



修飾子でマークされます。 (遅延読み込みの本質については、 関連データの読み取りで説明します )ナビゲーションプロパティに複数のエンティティ(多対多および1 ICollection



関係)を含めることができる場合、そのタイプはICollection



必要があります。



エンティティ登録


clip_image010



Modelsフォルダーで、 登録を作成します 次の内容のcs



 using System; using System.Collections.Generic; namespace ContosoUniversity.Models { public class Enrollment { public int EnrollmentID { get; set; } public int CourseID { get; set; } public int StudentID { get; set; } public decimal? Grade { get; set; } public virtual Course Course { get; set; } public virtual Student Student { get; set; } } }
      
      





decimal



後の疑問符は、 Grade



プロパティがnull値であることを示します。 nullに設定された評価はゼロ評価とは異なります。nullは評価がまだ設定されていないことを意味しますが、0は既に値です。



StudentID



プロパティは外部キーであり、対応するナビゲーションプロパティはStudent



です。 Enrollment



エンティティは1つのStudent



エンティティに関連付けられているため、プロパティには指定されたタイプの1つのエンティティのみを含めることができます( Enrollments



とは異なり.



)。



CourseID



プロパティは外部キーであり、対応するナビゲーションプロパティはCourse



です。 Enrollment



エンティティは、1つのCourse



エンティティに関連付けられています。



エッセンスコース


clip_image011



Modelsフォルダーで、 コースを作成します 次の内容のcs



 using System; using System.Collections.Generic; namespace ContosoUniversity.Models { public class Course { public int CourseID { get; set; } public string Title { get; set; } public int Credits { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; } } }
      
      





Enrollments



プロパティ-ナビゲーションプロパティ。 Course



エンティティは、無制限のEnrollment



エンティティに関連付けることができます。



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



現在のデータモデルのEntity Frameworkの機能を調整するメインクラスは、 データベース コンテキストと呼ばれます 。 このクラスはSystem



継承しSystem



.



Data



Entity



DbContext



コードでは、データモデルに含めるエンティティを決定し、Entity Framework自体の動作を決定することもできます。 コードでは、このクラスはSchoolContext



と呼ばれます。



DALフォルダーを作成し、その中に新しいSchoolContextクラスを作成します cs



 using System; using System.Collections.Generic; using System.Data.Entity; using ContosoUniversity.Models; using System.Data.Entity.ModelConfiguration.Conventions; namespace ContosoUniversity.Models { public class SchoolContext : DbContext { 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の用語では、 エンティティ セットはデータベーステーブルを指し、エンティティはテーブル内のレコードを指します。



OnModelCreating







テーブル名を複数形から保護します。そうしないと、 Students



Courses



Enrollments



などのテーブル名を取得します。 それ以外の場合、テーブル名はStudent



Course



Enrollment



ます。 開発者は、テーブル名を複数形にするかどうかを議論します。 単一のフォームを使用しますが、重要なことは、この行をコードに含めるかどうかを選択できることです。



(このクラスはネームスペースモデルにあります。状況によっては、コードファーストアプローチでは同じネームスペースでエンティティクラスとコンテキストを見つける必要があるためです。)



接続文字列の定義



接続文字列を定義する必要はありません。 この行を定義しない場合、Entity Frameworkは自動的にSQL Server Expressデータベースを作成します。 ただし、SQL Server Compactで作業するため、これを示す接続文字列を作成する必要があります。



ウェブを開きます。 構成し、connectionStringsコレクションに新しい接続文字列を追加します。 ( Webを更新していることを確認してくださいプロジェクトのルートで構成します。Viewsフォルダーには別のWeb。 構成があります。変更する必要はありません 。)



 <add name="SchoolContext" connectionString="Data Source=|DataDirectory|School.sdf" providerName="System.Data.SqlServerCe.4.0"/>
      
      





既定では、Entity Frameworkは、オブジェクトコンテキストクラスとも呼ばれる接続文字列を検索します。 追加した接続文字列は、App_dataおよびSQL Server CompactフォルダーにあるSchool.sdfデータベースを定義します。



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



Entity Frameworkは、アプリケーションの起動時にデータベースを自動的に作成できます。 これは、アプリケーションが起動するたびに、またはモデルが既存のデータベースと同期していない場合にのみ発生するように指定できます。 また、テストデータで使用するデータベースを作成する前に、Entity Frameworkが自動的に呼び出すメソッドを使用してクラスを作成することもできます。 モデルが変更されたら、ベースを削除して再作成する必要があることを示します。



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 : 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 { Title = "Chemistry", Credits = 3, }, new Course { Title = "Microeconomics", Credits = 3, }, new Course { Title = "Macroeconomics", Credits = 3, }, new Course { Title = "Calculus", Credits = 4, }, new Course { Title = "Trigonometry", Credits = 4, }, new Course { Title = "Composition", Credits = 3, }, new Course { Title = "Literature", Credits = 4, } }; courses.ForEach(s => context.Courses.Add(s)); context.SaveChanges(); var enrollments = new List<Enrollment> { new Enrollment { StudentID = 1, CourseID = 1, Grade = 1 }, new Enrollment { StudentID = 1, CourseID = 2, Grade = 3 }, new Enrollment { StudentID = 1, CourseID = 3, Grade = 1 }, new Enrollment { StudentID = 2, CourseID = 4, Grade = 2 }, new Enrollment { StudentID = 2, CourseID = 5, Grade = 4 }, new Enrollment { StudentID = 2, CourseID = 6, Grade = 4 }, new Enrollment { StudentID = 3, CourseID = 1 }, new Enrollment { StudentID = 4, CourseID = 1, }, new Enrollment { StudentID = 4, CourseID = 2, Grade = 4 }, new Enrollment { StudentID = 5, CourseID = 3, Grade = 3 }, new Enrollment { StudentID = 6, CourseID = 4 }, new Enrollment { StudentID = 7, CourseID = 5, Grade = 2 }, }; enrollments.ForEach(s => context.Enrollments.Add(s)); context.SaveChanges(); } } }
      
      





Seed



メソッドは、ベースコンテキストオブジェクトを入力パラメーターとして受け取り、それを使用してデータベースに新しいエンティティを追加します。 コードは、エンティティタイプごとに、新しいエンティティのコレクションを作成し、それらを対応するDbSetプロパティに追加してから、データベースに変更を保存します。 エンティティの各グループの後にSaveChanges



を呼び出す必要はありませんが、これは私たちが行っているように、例外の場合に問題を識別するのに役立ちます。



グローバルを変更します。 asax。 アプリケーションが起動するたびにコードが呼び出されるようにcs



 using System.Data.Entity; using ContosoUniversity.Models; using ContosoUniversity.DAL;
      
      





 Database.SetInitializer<SchoolContext>(new SchoolInitializer());
      
      





アプリケーションは、アプリケーションの起動後、データベースへの最初のアクセスごとに、Entity Frameworkがデータベースとモデル( SchoolContext



クラス)を比較し、 SchoolContext



場合、アプリケーションがデータベースを削除して再作成するように構成されます。



実稼働サーバーにアプリケーションをデプロイするときは、テストデータでデータベースを初期化するすべてのコードを削除する必要があります。



次に、データを表示するWebページを作成します。データ要求プロセスが自動的にデータベースの作成を開始します。 新しいコントローラーから始めますが、その前にプロジェクトをまとめて、モデルとコンテキストクラスがMVCコントローラーの足場で利用できるようにします。



生徒用コントローラーの作成



Student



コントローラーを作成するには、 ソリューションエクスプローラーで[ コントローラー ]フォルダーをクリックし、[ 追加 ]、[ コントローラー ] クリックします 。 [ コントローラーの 追加 ]で、次のアクションと変更を行い、[ 追加 ] クリックします。



clip_image012



Controllers \ StudentControllerを開きます cs 、データベースコンテキストオブジェクトを初期化する作成された変数が表示されます。



  private SchoolContext db = new SchoolContext(); 


Index



アクションは、データベースコンテキストインスタンスのStudents



プロパティからStudents



リストを収集します。



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





自動足場は、さまざまなStudent



向けに作成されました。 見出しと列の順序をカスタマイズするには、 Views \ Student \ Indexを開きます。 cshtmlでコードを次のように置き換えます。



 @model IEnumerable<ContosoUniversity.Models.Student> @{ ViewBag.Title = "Students"; } <h2>Students</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table> <tr> <th></th> <th>Last Name</th> <th>First Name</th> <th>Enrollment Date</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>
      
      





サイトを起動し、「 学生」タブをクリックします。



clip_image002 [1]



ブラウザを閉じます。 ソリューションエクスプローラーで ContosoUniversity プロジェクトを 選択します 。 [ すべてのファイルを表示]、 [ 更新]の順にクリックし、 App_Dataフォルダーを展開します。



clip_image013



Schoolをダブルクリックします サーバー エクスプローラーを開くためのsdf 、およびテーブル



School.sdfをダブルクリックした後にエラーが発生した場合は SQL Server Compact 4.0 用の Visual Studio 2010 SP1 ツールがインストールされていることを確認してください。 すべてがインストールされたら、Visual Studioを再起動します。



clip_image014



各テーブルには、独自のエンティティセットと1つの追加テーブルがあります。 EdmMetadata



、モデルとベースが同期していない場合にEntity Frameworkを決定するために使用されます。



テーブルの1つをクリックし、テーブルデータを表示してSchoolInitializer



クラスによってロードされたデータを表示します。



clip_image015



接続を閉じます。そうしないと、アプリケーションの起動に問題がある可能性があります。



clip_image016



合意



Entity Frameworkの規則を使用しているため、Entity Frameworkの作成に必要なコードの量は最小限です。 それらのいくつかはすでに言及されています:



これらの契約は無効にできることがわかりました(たとえば、複数形をオフにすることができます)。これを行う方法の詳細については、「より複雑なデータモデルの作成」を参照してください



Entity FrameworkとSQL Server Compactを使用してデータを保存および表示する単純なアプリケーションを作成しました。 次に、簡単なCRUD(作成、読み取り、更新、削除)操作を実行する方法を学習します。



Alexander Belotserkovsky( ahriman )の翻訳にご協力いただきありがとうございます。



アプリ全体をダウンロード | PDFマニュアルのダウンロード



All Articles