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

Contoso University  Web 应用程序

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

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

Students_Index_page 

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

系统必备组件

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

Windows Azure SDK 以 Visual Studio 2012

如果你有安装了 Visual Studio,上面的链接将安装任何缺少的组件。如果你没有 Visual Studio,该链接将安装 Visual Studio 2012 速成网站。您可以使用 Visual Studio 2013 年,但某些所需的程序和屏幕会有所不同。

创建 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 项目对话框中选择的互联网应用模板。

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

单击确定.

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 (创建、 读取、 更新、 删除) 操作。你可以离开此页面底部的反馈。请让我们知道如何你喜欢本教程的这一部分,我们如何能改善它。

posted @ 2015-01-27 16:17  178mz  阅读(1533)  评论(0编辑  收藏  举报