EntityFramework_MVC4中EF5 新手入门教程之一 ---1.建立实体框架数据模型

Contoso University  Web 应用程序

你会在这些教程中构建的应用程序是一个简单的大学网站。css

用户能够查看和更新学生、 课程和教师信息。这里有几个屏幕,您将建立。html

Students_Index_page 

这个网站的用户界面样式一直接近由内置的模板,生成的内容,以便本教程能够集中主要精力如何使用实体框架。jquery

系统必备组件

方向和屏幕截图在本教程中假定您正在使用Visual Studio 2012Visual Studio 2012 速成网站,最新的更新与截至 2013 年 7 月,安装的 Windows Azure SDK。你能够获得这一切与下面的连接:web

Windows Azure SDK 以 Visual Studio 2012ajax

若是你有安装了 Visual Studio,上面的连接将安装任何缺乏的组件。若是你没有 Visual Studio,该连接将安装 Visual Studio 2012 速成网站。您可使用 Visual Studio 2013 年,但某些所需的程序和屏幕会有所不一样。sql

建立 MVC Web 应用程序

打开 Visual Studio 并建立一个新 C# 项目命名为"ContosoUniversity"使用ASP.NET MVC 4 Web 应用程序模板。请确保您的目标.NET 框架 4.5 (你会使用enum的属性,而且,须要.NET 4.5)。数据库

New_project_dialog_box

新的 ASP.NET MVC 4 项目对话框中选择的互联网应用模板。express

Razor视图引擎选择,和建立一个单元测试项目的复选框处于清除状态的假期。canvas

单击肯定.api

Project_template_options

创建了该网站的风格

几个简单的改变将设立网站菜单、 布局和主页。

打开Views\Shared\_Layout.cshtml,而后用如下代码替换该文件的内容。突出显示所作的更改。

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>@ViewBag.Title - Contoso University</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <header> <div class="content-wrapper"> <div class="float-left"> <p class="site-title">@Html.ActionLink("Contoso University", "Index", "Home")</p> </div> <div class="float-right"> <section id="login"> @Html.Partial("_LoginPartial") </section> <nav> <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> </nav> </div> </div> </header> <div id="body"> @RenderSection("featured", required: false) <section class="content-wrapper main-content clear-fix"> @RenderBody() </section> </div> <footer> <div class="content-wrapper"> <div class="float-left"> <p>&copy; @DateTime.Now.Year - Contoso University</p> </div> </div> </footer> @Scripts.Render("~/bundles/jquery") @RenderSection("scripts", required: false) </body> </html>

这段代码进行如下更改:

  • "个人 ASP.NET MVC 应用程序"和"您的徽标在这里"的模板实例替换为"Contoso University"。
  • 添加将使用在本教程后面的几个操做环节。

Views\Home\Index.cshtml,用如下代码,以消除有关 ASP.NET 和 MVC 模板段落替换该文件的内容:

@{
    ViewBag.Title = "Home Page";
}
@section featured {
    <section class="featured"> <div class="content-wrapper"> <hgroup class="title"> <h1>@ViewBag.Title.</h1> <h2>@ViewBag.Message</h2> </hgroup> </div> </section> }

Controllers\HomeController.cs,将值更改成ViewBag.Message Index操做方法中为"欢迎来到 Contoso 大学 !",以下面的示例所示:

public ActionResult Index() { ViewBag.Message = "Welcome to Contoso University"; return View(); }

按 CTRL + F5 以运行网站。你看到主页与主菜单。

Contoso_University_home_page

建立数据模型

接下来,您将建立实体类为 Contoso University 中的应用。你将开始与如下三个实体:

Class_diagram

还有StudentEnrollment实体之间的一个一对多关系和CourseEnrollment实体之间是一对多的关系。换句话说,学生能够在任意数量的课程,并固然能够有任意数量的学生参加了它。

在如下部分中,您将建立一个类,用于每一个这些实体。

若是您尝试编译该项目,在您完成全部这些实体类的建立以前,你就会获得编译器错误。

学生实体

Student_entity

模型文件夹中,建立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属性将成为此类对应的数据库表的主键列。默认状况下,实体框架将解释是命名的ID类名ID做为主键的属性。

Enrollments属性是一个导航属性导航属性持有此实体相关的其余实体。在这种状况下,一个Student实体的Enrollments属性将保留全部的Enrollment实体的那个Student实体相关的。换言之,若是某一给定的Student行在数据库中有两个相关的Enrollment行 (包含在其StudentID的外键列中的那个学生主键值的行),该Student实体Enrollments导航属性将包含这两个Enrollment实体。

导航属性一般定义为virtual中,以便他们能够利用某些实体框架功能,如延迟加载(延迟加载将稍后解释,读取相关数据教程稍后在本系列中。

若是一个导航属性能够容纳多个实体 (如多多或一个一对多关系),其类型必须是一个列表条目能够被添加、 删除和更新,如ICollection.

注册实体

Enrollment_entity

模型文件夹中,建立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; } } }

等级属性是枚举问号后Grade类型声明指示Grade属性是能够为 null为 null 的品位是不一样于零级 — — null 意味着等级鲜为人知或没有被指派。

StudentID属性是一个外键,且相应的导航属性是StudentEnrollment实体是与一个Student实体相关联,因此该属性只能容纳一个单一的Student实体 (不像Student.Enrollments导航属性你前面所述,而数组能够存放多个Enrollment实体)。

CourseID属性是一个外键,且相应的导航属性CourseEnrollment实体是与一个Course实体相关联。

课程实体

Course_entity

模型文件夹中,建立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属性是一个导航属性。Course实体能够与任意数量的Enrollment实体。

咱们会说更多关于[DatabaseGenerated(DatabaseGeneratedOption.None)] 在接下来的教程中的属性。基本上,此属性容许您为该课程而不是生成的数据库输入的主键。

建立Database Context

坐标给定的数据模型的实体框架功能的主类是数据库上下文类。经过从System.Data.Entity.DbContext类派生来建立此类。在您的代码中您指定数据模型中包括哪些实体。您还能够自定义某些实体框架行为。在这个项目中,类名为SchoolContext.

建立一个文件夹命名DAL (为数据访问层)。在该文件夹中建立一个新的类文件,命名为SchoolContext.cs,和现有的代码替换为如下代码:

using ContosoUniversity.Models; using System.Data.Entity; using System.Data.Entity.ModelConfiguration.Conventions; namespace ContosoUniversity.DAL { 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属性为每一个实体集。在实体框架术语中,实体集一般对应于数据库表,和一个实体对应于表中的一行。

OnModelCreating方法中的modelBuilder.Conventions.Remove语句能够防止表名称正在趋向多元化。若是你不这样作,所生成的表将命名为StudentsCoursesEnrollments相反,表名称将是StudentCourse、 及Enrollment表名称应该多数开发商不一样意。本教程使用的是单数形式,但重要的一点是您能够选择哪一个你更喜欢经过包括或省略下面这行代码的形式。

SQL 服务器快递 LocalDB

LocalDB是一个轻量级版本 SQL Server 表示数据库引擎的按需启动和运行在用户模式下。LocalDB 运行的 SQL Server Express 使您可以使用数据库的.mdf文件做为特殊的执行方式。一般状况下,LocalDB 数据库文件保存在 web 项目的App_Data文件夹中。在 SQL Server Express用户实例功能还使您可以使用.mdf文件,但不推荐使用用户实例的功能 ;所以,LocalDB 被推荐使用的.mdf文件。

一般 SQL Server Express 的并不用于生产的 web 应用程序。LocalDB 尤为不推荐用于生产一个 web 应用程序由于它不设计工做的非法入境者。

在 Visual Studio 2012 及之后的版本中,默认状况下,Visual Studio 安装 LocalDB。在 Visual Studio 2010 及更早版本中,在默认状况下,Visual Studio ; 安装 SQL Server Express (无 LocalDB)您必须手动安装它,若是你使用的 Visual Studio 2010。

在本教程中您将使用 LocalDB,以便数据库能够存储在.mdf文件所在的App_Data文件夹中。打开根Web.config文件并到connectionStrings集合中,添加一个新的链接字符串,以下面的示例所示。(请确保您更新Web.config文件中的根项目文件夹。此外,还有 Web.config文件是您不须要更新的视图子文件夹中。)

 <add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=ContosoUniversity;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\ContosoUniversity.mdf" providerName="System.Data.SqlClient" />

默认状况下,实体框架查找名为DbContext类 (此项目SchoolContext ) 相同的链接字符串。您已经添加的链接字符串指定一个名为ContosoUniversity.mdf位于App_Data文件夹中的 LocalDB 数据库。更多的信息,请参见ASP.NET Web 应用程序的 SQL 服务器链接字符串.

实际上,您不须要指定的链接字符串。若是您不提供链接字符串,实体框架将建立一个为您 ;可是,数据库可能没法在您的应用程序的App_data文件夹中。将建立数据库的信息,请参见代码第一次到新的数据库.

connectionStrings集合还具备一个名为DefaultConnection的用于成员资格数据库的链接字符串。在本教程中,您不会使用成员资格数据库。两个链接字符串之间的惟一区别是数据库名称和名称属性值。

设置和执行代码第一次迁移

当你第一次开始开发应用程序时,您的数据模型更改频繁,并且每次获取与数据库不一样步的模型更改。您能够配置实体框架能够自动删除并从新建立该数据库的每次更改数据模型。这不是一个问题在开发的早期,由于测试数据是很容易从新建立,可是您已经部署到生产后你一般想要更新数据库架构,而不删除数据库。迁移功能使代码第一要更新数据库,而不会删除并从新建立它。早在开发周期中的一个新的项目你可能想要使用DropCreateDatabaseIfModelChanges ,能够删除、 从新建立和从新设置为种子数据库每次模型更改。一我的,你准备部署您的应用程序,您能够转换为的迁移方法。在本教程中,您将仅使用迁移。有关的详细信息,请参见代码第一次迁移迁移截屏视频系列.

启用代码第一次迁移

  1. 工具菜单上,单击库程序包管理器,而后程序包管理器控制台.

    Selecting_Package_Manager_Console

  2. PM>提示符下输入如下命令:

    enable-migrations -contexttypename SchoolContext

    enable-migrations command

    此命令在 ContosoUniversity 项目中,建立一个迁移文件夹和它在该文件夹中放一个Configuration.cs文件,您能够编辑配置迁移。

    Migrations folder

    Configuration类包括建立数据库时,每次更新数据模型更改后调用的Seed方法。

    internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.Models.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.Models.SchoolContext context) { // This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method  // to avoid creating duplicate seed data. E.g. // // context.People.AddOrUpdate( // p => p.FullName, // new Person { FullName = "Andrew Peters" }, // new Person { FullName = "Brice Lambson" }, // new Person { FullName = "Rowan Miller" } // ); // } }

    Seed方法的目的是使您可以向数据库中插入测试数据后代码第一次建立或更新它。

创建了种子法

种子方法运行时代码第一次迁移建立数据库和每一次它将更新到最新的迁移数据库。种子法的目的是为了使您可以将数据插入到表以前应用程序访问数据库第一次。

在早期版本的代码优先,迁移被释放以前,它是日常的Seed方法来插入测试数据,由于在开发过程当中的每一个模型修改数据库不得不被彻底删除和从新建立从零开始。与代码第一次迁移,测试数据保留后数据库更改,所以包括种子方法中的测试数据一般不是必需。事实上,你不想要插入测试数据,若是您将使用迁移将数据库部署到生产,由于Seed方法将运行在生产中的Seed 方法。在这种状况下你但愿Seed 方法向数据库中插入你想要在生产中插入的数据。例如,您可能想要包括实际部门名称Department表中,当应用程序在生产中可用的数据库。

对于本教程,您将使用迁移的部署,但你的Seed 方法将插入测试数据不管如何为了使它更加轻松地查看应用程序的功能而无需手动插入大量的数据的工做。

  1. Configuration.cs文件的内容替换为如下代码中,将测试数据加载到新的数据库。
    namespace ContosoUniversity.Migrations { using System; using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using ContosoUniversity.Models; internal sealed class Configuration : DbMigrationsConfiguration<ContosoUniversity.DAL.SchoolContext> { public Configuration() { AutomaticMigrationsEnabled = false; } protected override void Seed(ContosoUniversity.DAL.SchoolContext context) { var students = new List<Student> { new Student { FirstMidName = "Carson", LastName = "Alexander", EnrollmentDate = DateTime.Parse("2010-09-01") }, new Student { FirstMidName = "Meredith", LastName = "Alonso", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Arturo", LastName = "Anand", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Gytis", LastName = "Barzdukas", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Yan", LastName = "Li", EnrollmentDate = DateTime.Parse("2012-09-01") }, new Student { FirstMidName = "Peggy", LastName = "Justice", EnrollmentDate = DateTime.Parse("2011-09-01") }, new Student { FirstMidName = "Laura", LastName = "Norman", EnrollmentDate = DateTime.Parse("2013-09-01") }, new Student { FirstMidName = "Nino", LastName = "Olivetto", EnrollmentDate = DateTime.Parse("2005-08-11") } }; students.ForEach(s => context.Students.AddOrUpdate(p => p.LastName, 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,},newCourse{CourseID=3141,Title="Trigonometry",Credits=4,},newCourse{CourseID=2021,Title="Composition",Credits=3,},newCourse{CourseID=2042,Title="Literature",Credits=4,}}; courses.ForEach(s => context.Courses.AddOrUpdate(p => p.Title, s)); context.SaveChanges();var enrollments =newList<Enrollment>{newEnrollment{StudentID= students.Single(s => s.LastName=="Alexander").StudentID,CourseID= courses.Single(c => c.Title=="Chemistry").CourseID,Grade=Grade.A },newEnrollment{StudentID= students.Single(s => s.LastName=="Alexander").StudentID,CourseID= courses.Single(c => c.Title=="Microeconomics").CourseID,Grade=Grade.C },newEnrollment{StudentID= students.Single(s => s.LastName=="Alexander").StudentID,CourseID= courses.Single(c => c.Title=="Macroeconomics").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Alonso").StudentID,CourseID= courses.Single(c => c.Title=="Calculus").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Alonso").StudentID,CourseID= courses.Single(c => c.Title=="Trigonometry").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Alonso").StudentID,CourseID= courses.Single(c => c.Title=="Composition").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Anand").StudentID,CourseID= courses.Single(c => c.Title=="Chemistry").CourseID},newEnrollment{StudentID= students.Single(s => s.LastName=="Anand").StudentID,CourseID= courses.Single(c => c.Title=="Microeconomics").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Barzdukas").StudentID,CourseID= courses.Single(c => c.Title=="Chemistry").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Li").StudentID,CourseID= courses.Single(c => c.Title=="Composition").CourseID,Grade=Grade.B },newEnrollment{StudentID= students.Single(s => s.LastName=="Justice").StudentID,CourseID= courses.Single(c => c.Title=="Literature").CourseID,Grade=Grade.B }};foreach(Enrollment e in enrollments){var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID== e.StudentID&& s.Course.CourseID== e.CourseID).SingleOrDefault();if(enrollmentInDataBase ==null){ context.Enrollments.Add(e);}} context.SaveChanges();}}}

    种子方法采用数据库上下文对象做为输入参数和方法中的代码使用该对象来向数据库中添加新的实体。代码为每一个实体类型,建立一个新的实体的集合,将它们添加到适当的DbSet属性,而后将所作的更改保存到数据库。这是没有必要后每一个组的实体,调用SaveChanges方法,由于在这里,但这样作能够帮助你找到问题的根源,若是向数据库写入代码时发生的异常。

    一些插入数据的语句使用AddOrUpdate方法执行"upsert"操做。由于Seed 方法运行与每一个迁移时,你不能只是将数据插入,由于您试图添加的行就已经在那里建立数据库的第一次迁移后。"Upsert"操做能够防止错误若是您尝试插入行已经存在,但它将重写将会发生任何更改你可能已经在测试应用程序时的数据。用测试数据在某些表中您可能不但愿这样的事情发生: 在某些状况下当您更改数据在测试时你想要更改数据库更新后继续。在这种状况下,你想要作一个有条件的插入操做: 插入行,只有当它不存在。种子方法使用这两种方法。

    第一个参数传递给AddOrUpdate方法指定要用来检查是否已存在的行的属性。为您提供的学生 (测试) 数据,LastName属性能够用于此目的由于每一个列表中的最后一个名称是惟一的:

    context.Students.AddOrUpdate(p => p.LastName, s)

    此代码假定最后一名是惟一的。若是您手动添加具备重复的姓氏的一名学生,你会获得下面的异常下次您执行迁移。

    序列包含一个以上的元素

    AddOrUpdate方法的更多信息,请参阅在 Julie Lerman 博客上的照顾与 EF 4.3 AddOrUpdate 方法

    添加Enrollment实体的代码不使用 AddOrUpdate方法。它会检查是否实体已经存在,而且插入实体,若是它不存在。这种方法将保留到入学年级迁移运行时所作的更改。代码遍历每一个成员的Enrollment 列表,若是在数据库中找不到注册,它向数据库中添加注册。第一次你更新数据库,数据库将为空,因此它将添加每一个招生。

    foreach (Enrollment e in enrollments) { var enrollmentInDataBase = context.Enrollments.Where( s => s.Student.StudentID == e.Student.StudentID && s.Course.CourseID == e.Course.CourseID).SingleOrDefault(); if (enrollmentInDataBase == null) { context.Enrollments.Add(e); } }

    有关如何调试Seed 方法以及如何处理多余的数据,如命名为"亚历山大 · 卡森"的两个学生的信息,请参阅在里克 • 安德森的博客上的播种及调试实体框架 (EF) 星展银行

  2. 生成项目。

建立和执行第一次迁移

  1. 在程序包管理器控制台窗口中,输入如下命令:
    add-migration InitialCreate update-database

    add-migration命令将添加到迁移文件夹[DateStamp]_InitialCreate.cs文件,其中包含建立数据库的代码。第一个参数 (InitialCreate)用于文件的名称,而且能够是任何你想要的 ;你一般选择的单词或短语总结了正在作迁移中。例如,您可能会命名之后迁移"AddDepartmentTable"。

    Migrations folder with initial migration

    UpInitialCreate类的方法建立的数据库表,对应于数据模型实体集,并 Down方法删除它们。迁移调用Up方法来执行数据模型更改成迁移。当你输入一个命令来回滚更新时,迁移调用Down方法。下面的代码演示了InitialCreate 文件的内容:

    namespace ContosoUniversity.Migrations { using System; using System.Data.Entity.Migrations; public partial class InitialCreate : DbMigration { public override void Up() { CreateTable( "dbo.Student", c => new { StudentID = c.Int(nullable: false, identity: true), LastName = c.String(), FirstMidName = c.String(), EnrollmentDate = c.DateTime(nullable: false), }) .PrimaryKey(t => t.StudentID); CreateTable( "dbo.Enrollment", c => new { EnrollmentID = c.Int(nullable: false, identity: true), CourseID = c.Int(nullable: false), StudentID = c.Int(nullable: false), Grade = c.Int(), }) .PrimaryKey(t => t.EnrollmentID) .ForeignKey("dbo.Course", t => t.CourseID, cascadeDelete: true) .ForeignKey("dbo.Student", t => t.StudentID, cascadeDelete: true) .Index(t => t.CourseID) .Index(t => t.StudentID); CreateTable( "dbo.Course", c => new { CourseID = c.Int(nullable: false), Title = c.String(), Credits = c.Int(nullable: false), }) .PrimaryKey(t => t.CourseID); } public override void Down() { DropIndex("dbo.Enrollment", new[] { "StudentID" }); DropIndex("dbo.Enrollment", new[] { "CourseID" }); DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student"); DropForeignKey("dbo.Enrollment", "CourseID", "dbo.Course"); DropTable("dbo.Course"); DropTable("dbo.Enrollment"); DropTable("dbo.Student"); } } }

    update-database命令运行Up方法来建立数据库,而后它运行Seed 方法来填充该数据库。

如今前,该署为您的数据模型,建立一个 SQL Server 数据库。数据库的名称是ContosoUniversity,和.mdf文件是在您的项目的App_Data文件夹中,由于那是您在您的链接字符串中指定。

你可使用服务器资源管理器SQL 服务器对象资源管理器(SSOX) 在 Visual Studio 中查看的数据库。在本教程中,您将使用服务器资源管理器在 Visual Studio 表达 2012 网站,服务器资源管理器调用数据库资源管理器.

  1. 视图菜单上,单击服务器资源管理器.

  2. 单击添加链接图标。



  3. 若是系统提示您与选择数据源对话框中,单击Microsoft SQL Server,而后单击继续.

  4. 添加链接对话框中,输入服务器名称 (localdb) \v11.0 。选择或输入数据库名称下,选择ContosoUniversity.

  5. 单击OK。

  6. 展开SchoolContext ,而后展开.

  7. 右键单击学生表,单击显示表数据,请参阅建立列和被插入到表中的行。

    Student table 

建立学生控制器和视图

下一步是建立 ASP.NET MVC 控制器和视图在您的应用程序可使用这些表之一。

  1. 若要建立一个Student控制器,用鼠标右键单击控制器文件夹中的解决方案资源管理器中,选择添加,,而后单击控制器添加控制器对话框中,选择如下选项,而后单击添加:
    • 控制器的名称: StudentController.
    • 模板: MVC 控制器的读/写操做和视图,使用实体框架.
    • 模型类:学生 (ContosoUniversity.Models)(若是看不到此选项在下拉列表中的,生成项目,并再试一次)。
    • 数据上下文类: SchoolContext (ContosoUniversity.Models).
    • 视图:Razor (CSHTML)(默认值)。

    Add_Controller_dialog_box_for_Student_controller

  2. Visual Studio 会打开Controllers\StudentController.cs文件。你看到一个类变量已建立该实例化数据库上下文对象:

    private SchoolContext db = new SchoolContext();

    Index操做方法从学生实体经过读取数据库上下文实例Students属性设置获取学生列表:

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

    Student\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.StudentID }) | @Html.ActionLink("Details", "Details", new { id=item.StudentID }) | @Html.ActionLink("Delete", "Delete", new { id=item.StudentID }) </td> </tr> }
  3. 按 CTRL + F5 以运行该项目。

    单击学生选项卡以查看 Seed方法插入的测试数据。

    Student Index page

公约

因为采用了各项公约或使实体框架的假设,你不得不为实体框架,以便可以为您建立一个完整的数据库按顺序写的代码量很小。其中一些已经被注意到:

  • 多元化的形式的实体类的名字被用做表名称。
  • 实体属性名称用于列的名称。
  • 被命名为ID类名ID的实体属性被视为首要的关键属性。

你见过能够覆盖公约 (例如,您指定不该该多元化表名称),而且您将了解更多关于各项公约以及如何建立一个更复杂的数据模型后来在这个系列教程中重写它们。更多的信息,请参阅代码第一次约定.

摘要

如今,您已经建立一个简单的应用程序,使用实体框架和 SQL Server Express 来存储和显示数据。在下面的教程中,您将学习如何执行基本的 CRUD (建立、 读取、 更新、 删除) 操做。你能够离开此页面底部的反馈。请让咱们知道如何你喜欢本教程的这一部分,咱们如何能改善它。

相关文章
相关标签/搜索