(譯)給ASP.NET MVC 創建一個實體數據模型(一)


源碼下載    原文地址

        Contoso 大學 Web 示例應用演示了如何使用 EF5 技術創建 ASP.NET MVC 應用。這個例子是Contoso大學的官網。應用包括了類似學生注冊、課程創建以及教師分配等功能。這個系列教程展示了創建 Contoso 大學應用的步驟。你可以下載完整的例子 。

編碼優先原則

       EF( Entity Framework)提供3種方式來處理數據:數據庫優先(Database First),模型優先( Model First)和編碼優先(Code First).這些課程采用的是編碼優先原則。關於這三者的區別,工作流程以及如何選擇其中的一種作為你的方案,請瀏覽Entity Framework Development Workflows.

MVC

        應用程序 采用 ASP.NET MVC設計方式。如果你更喜歡 ASP.NET Web Forms 模式,請瀏覽Model Binding and Web Forms  系列課程Model Binding and Web Forms文章。
Contoso 大學網站應用程序

在這個教程中你將創建的應用是一個簡單的大學網站。

 

由於教程主要關注於如何使用 EF ,所以界面的風格與內置模板的風格保持一致。

EF 開發方法

下圖所示,存在三種方式來使用 EF:數據庫優先,模型優先和代碼優先。

數據庫優先

如果你已經創建了數據庫,EF 可以自動生成創建數據模型,包含關聯到數據庫中表和字段的類和屬性。關於數據庫結構的信息(存儲架構)、數據模型(概念模型)、它們之間的映射被存儲在擴 展名為 .edmx 的 XML 文件中。Visual Studio 提供了 EF 設計器,這是一個圖形化的設計器,可以用來顯示和編輯 .edmx 文件。Getting Started With the Entity Framework  和 Continuing With the Entity Framework 介紹了使用數據庫優先的開發。

模型優先

如果你還沒有數據庫,你可以在 Visual Stdio 中使用 EF 的設計器通過創建模型來開始。當模型創建之后,設計器可以生成 DDL 語句來創建相應的數據庫。這個方法也使用 .edmx 文件來存儲模型以及映射信息。 What's New in the Entity Framework 4 介紹了模型優先的開發。

代碼優先

不管你是否已經有數據庫,你仍然可以編寫自己的類和數據關聯到數據表和字段,使用 EF 而不需要 .edmx 文件。所有有時候這種方法又被稱為 Code Onle。當然經典的名稱為 Code First。在數據庫的存儲架構到概念模型之間的映射通過約定以及特定的映射 API 完成。如果你還沒有數據庫,EF 可以自動為你創建它,在模型改變的時候,先刪除掉然后重新創建,這個教程使用代碼優先的方式進行開發。

使用代碼優先的方式進行數據庫訪問的 API 基於 DbContext 類。這也同樣可以用於數據庫優先或者模型優先的開發流程。 更多詳細的內容,可以看 When is Code First not code first?

POCO (簡單的老的 CLR 對象)

默認情況下,當你使用數據庫優先或者模型優先開發方法的時候,你的數據模型對象需要派生自 EntityObject 類,通過它提供 EF 功能。這意味着這些類不能是 持久性無感知(persistence ignorant ) 的,所以不能符合領域驅動開發的要求。所有的 EF 開發方法都支持使用 POCO 類,由於不需要派生自 EntityObject ,所以,這樣的類是持久性無感知的。在這個教程中,我們將會使用 POCO 類。

創建一個WebMvc應用程序:

設置站點的風格:

通過一些簡單的修改來設置站點的菜單,布局和主頁。

打開 Views\Share\_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>

 代碼變化如下:

  • 用"Contoso University"替換 "My ASP.NET MVC Application" 和"your logo here"。
  • 增加了一些后面要用到的響應連接。

Views\Home\Index.cshtml頁面中把內容替換為下面的內容:

@{
    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文件中,將 "歡迎使用 ASP.NET MVC!" 替換為 "歡迎來到 Contoso University!"

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

    return View();
}

按下ctrl+F5 運行網站你可以看到主頁和主菜單如下:

 創建數據模型

 下一步,需要創建 Contoso 大學應用的第一組實體類,從下面的三個實體開始。

在學生 (Student) 實體和 注冊 (Enrollment) 實體之間存在一對多的關聯, 在課程 (Course) 和 注冊 (Enrollment) 之間也存在一對多的關聯。或者說,一個學生可以注冊許多課程,一個課程可以被許多學生注冊。

下面的時間,你需要為每個實體創建相應的類。

注意:如果你在創建完成所有這些類的時候編譯程序,將會看到編譯錯誤。

學生實體

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 屬性將會映射到數據庫中關聯到這個類的表的主鍵,默認情況下,EF 將屬性名為 ID 或者 類名ID 的屬性作為主鍵。

Enrollments 屬性是導航屬性,導航屬性用來導航到這個實體關聯的其他實體。Student 類的 Enrollments 屬性用來持有這個學生關聯的所有注冊實體。或者說,如果在數據庫中,一個學生行有兩個關聯的注冊行(通過 StudentId 這個外鍵關聯到學生表),學生實體的注冊屬性將會包含包含兩個注冊實體。

導航屬性典型地被定義為虛擬的 virtual,以便通過 EF 名為延遲加載的功能來獲得好處,(延遲加載將在后面進行說明),如果導航屬性可以持有多個實體,(在多對多情況下,或者一對多情況下),類型必須為 ICollection。

注冊實體

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; }
    }
}

Grade 是一個枚舉。在Grade類型后面加一個?問號表示Grade屬性值可以為空。空和0是不一樣的,空表示沒成績,0表示成績是0。

StudentID
屬性是一個外鍵,關聯的導航屬性是Student類。一個 Enrollment 關聯一個 Student,所以這個屬性只能持有一個 Student 實體 (不像 Student.Enrollments 導航屬性)。

CourseID 屬性也是外鍵,關聯的導航屬性為 Course,一個 Enrollment 關聯一個 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屬性是一個導航屬性,一個課程實體可以關聯多個Enrollments實體。

下節課我們會更多的來講解[DatabaseGenerated(DatabaseGeneratedOption.None)]。屬性的作用就是課程表的主鍵是要主動輸入的而不是用數據庫自動生成,即不是自增。

創建數據庫上下文

在 EF 中,主要的協調數據訪問功能的類是數據庫上下文類。你創建的這個類必須繼承自 System.Data.Entity.DbContext類。在你的代碼中指定數據模型中包含的實體。你可以定制某些 EF 的行為。在這個項目中,這個類的名字為 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 屬性,在 EF 術語中,一個實體集典型地關聯到一個數據庫中的表,一個實體關聯到表中的一行。一個實體集典型地關聯到一個數據庫中的表,一個實體關聯到表中的一行。在 OnModelCreating 方法中的代碼防止數據庫中的表名被多元化。如果沒有這樣處理的話,生成的表將會被命名為 Students,Courses 和 Enrollments。現在,表名將會被命名為 Student,Course 和 Enrollment。開發者可以決定表名是否被多元化。這個教程使用單數模式,但是重要的是你可以這行代碼來選擇喜歡的模式。

(這個類位於 Models 命名空間,有些時候 EF 假定實體類和上下文類在相同的命名空間中)

設置連接字符串

你還沒有創建數據庫連接串,如果你不去創建它,EF 將會自動為你創建一個 SQL Server Express 的數據庫。這個教程中,你將要使用 SQL Server Compact,所以,需要你來創建一個數據庫連接串。

打開項目的 web.config 文件,在 connectionStrings 配置中增加一個新的數據庫連接串,如下所示,(確信是項目根目錄中的 web.config ,注意在 Views 中還有一個,你不需要更新它)

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

 默認情況下,EF 查找與數據庫上下文類同名的數據庫連接串。你現在添加的鏈接串將會導致在 App_Data 文件夾中創建名為 School.sdf 的 SQL Server Compact 數據庫文件。

實際上你不需要創建連接字符串,如果你不指定字符串,EF會自動給你創建一個。因此數據庫就不再app項目下的App_data folder文件中。想知道數據庫是創建在那里的請閱讀 Code First to a New Database. connectionStrings集合包含一個默認的連接字符串DefaultConnection作為關聯數據庫的串。本例子中不需要用成員數據庫,兩個連串的區別僅僅是字符串的name和name對應的值。

設置執行Code First Migration

當我們開始開發應用程序的時候,需要頻繁的更新data model中的實體,每一次的更新,模型中的字段就和數據庫中的字段不一致了,所有我們需要配置,讓程序自動的刪除和重新創建數據庫。前期開發中我們用的都是測試數據,這樣做不會存在什么問題,當產品發布,部署以后,你只是希望更新數據庫,而不是刪除重建。Migrations 特點就是確保代碼優先來更新數據庫而不是刪除重建。起初的開發環境中,當模型改變的時候,你需要使用 DropCreateDatabaseIfModelChanges 來刪除,重建和補充數據庫。當你覺得部署程序后,你就可以轉換成migrations方法。更多詳情請參見:Code First MigrationsMigrations Screencast Series.

開啟Enable Code First Migrations

Tools 菜單, 點擊Library Package Manager 然后雙擊打開 Package Manager Console.

PM> prompt enter the following command:

輸入

enable-migrations -contexttypename SchoolContext

 這個命令就會在ContosoUniversity項目中創建一個Migrations文件夾,並且增加一個Configuration.cs 文件。

 

 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的目的就是 Code First創建或者更新的時候插入測試數據。

設置 Seed 方法

 Code First Migrations創建或者更新數據庫的時候,seed會運行,目的就是確保在你從數據庫讀取數據之前插入測試數據。

Code First早期版本中,Migrations 還沒發布之前,Seed被用來插入測試數據。因為當模型改變的時候,數據庫會被完全刪除重建。有了Code First Migrations,數據庫改變,測試數據會被保留。所有Seed方法中沒必要包含測試數據了。

事實上如果你使用Migrations來部署產品的數據庫,你不希望seed來插入測試數據,因為seed方法會在產品中運行。除非你希望seed方法來向數據庫中插入一些你期望插入的數據,比如默認數據。比如,你想在數據庫中的部門表里面插入真實的有用的部門名稱。

本教材中使用migrations來部署,但是你的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, },
                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.AddOrUpdate(p => p.Title, s));
         context.SaveChanges();

         var enrollments = new List<Enrollment>
            {
                new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").StudentID, 
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID, 
                    Grade = Grade.A 
                },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics" ).CourseID, 
                    Grade = Grade.C 
                 },                            
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Alexander").StudentID,
                    CourseID = courses.Single(c => c.Title == "Macroeconomics" ).CourseID, 
                    Grade = Grade.B
                 },
                 new Enrollment { 
                     StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                    CourseID = courses.Single(c => c.Title == "Calculus" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment { 
                     StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                    CourseID = courses.Single(c => c.Title == "Trigonometry" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment {
                    StudentID = students.Single(s => s.LastName == "Alonso").StudentID,
                    CourseID = courses.Single(c => c.Title == "Composition" ).CourseID, 
                    Grade = Grade.B 
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Anand").StudentID,
                    CourseID = courses.Single(c => c.Title == "Chemistry" ).CourseID
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Anand").StudentID,
                    CourseID = courses.Single(c => c.Title == "Microeconomics").CourseID,
                    Grade = Grade.B         
                 },
                new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Barzdukas").StudentID,
                    CourseID = courses.Single(c => c.Title == "Chemistry").CourseID,
                    Grade = Grade.B         
                 },
                 new Enrollment { 
                    StudentID = students.Single(s => s.LastName == "Li").StudentID,
                    CourseID = courses.Single(c => c.Title == "Composition").CourseID,
                    Grade = Grade.B         
                 },
                 new Enrollment { 
                    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();
      }
   }
}

 Seed  方法把數據庫context對象轉換為輸入參數,在這個方法中通過這個對象把實體插入數據庫中。對於每一個實體類型,代碼都會創建一個新的實體集合,然后把他們添加到對應的DbSet屬性中。然后保存到數據庫中。並不是每一個實體都需要調用SaveChanges方法,這里這么做,主要是來定位錯誤。

有些地方聲明使用 AddOrUpdate 方法來插入數據,表示更新。

因為Seed在每一次 migration的時候都會執行,你不僅僅是執行插入數據,因為有些數據在你第一次migration創建數據庫的時候就已經插入了,"upsert"操作就阻止了當你執行插入數據使該數據已經存在所拋出的錯誤,但是它重寫了很多改變方法,你可能需要做一些測試。

測試數據的時候你可能不想看到這樣的事情發生:在某些情況下當你改變數據在測試數據庫后,您希望您的更改保持更新。在這種情況下你想做一個有條件的插入操作:如果數據不存在,才插入。Seed方法包含了這兩種方式。

AddOrUpdate的第一個參數表示指定你需要判斷數據是否存在的字段。在你做的測試student表的數據中,LastName屬性就是來作為第一個參數的,來判斷這個值是不是已經存在。因為LastName是唯一的不可重復的。
context.Students.AddOrUpdate(p => p.LastName, s)

這行代碼表示LastName是唯一的。如果你手動插入一條重復的LastName的學生信息,下一次你migration的時候就會看到下面的錯誤:

Sequence contains more than one element

關於AddOrUpdate方法的更多信息,請參考: Take care with EF 4.3 AddOrUpdate Method

代碼中Enrollment實體沒有使用AddOrUpdate方法。它判斷了該實體是否已經存在,不存在則插入。foreach方法循環判斷Enrollment表,如果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方式參考: Seeding and Debugging Entity Framework (EF) DBs

生成項目:

創建執行第一次Migration

在Package Manager Console窗口中輸入以下命令:

add-migration InitialCreate
update-database

 

add-migration命令會在Migrations文件夾中增加一個InitialCreate.cs文件,文件包含了創建數據庫的代碼。命令中第一個參數 (InitialCreate)可以自己隨意指定。

InitialCreate類中的 Up 方法,用來創建數據庫來和模型中的實體集保持一致。Down方法用來刪除操作。Migrations 調用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方法來構建(初始化)數據庫。

此時sqlserver中已經創建了和模型一致的數據庫,數據庫名字是:ContosoUniversity .mdf文件在你的項目中 App_Data文件夾下,因為這些都是你在連接字符串中指定的。
在Visual Studio中你可以使用 Server Explorer或者Explorer (SSOX)來查看數據庫。在In Visual Studio Express 2012中,Server Explorer 被叫做 Database Explorer.

  1. 點擊 View 按鈕, 打開Server Explorer.

  2. 點擊 Add Connection 圖標.

3.如果彈出選擇數據庫對話框,選擇Microsoft SQL Server 點擊continue。

4.在Add Connection 對話框輸入(localdb)\v11.0 作為 Server Name. Select or enter a database name, 選擇ContosoUniversity.


5點擊OK。
6.展開  SchoolContext 展開 Tables.

7.右擊 Student 表 點擊 Show Table Data  就可以看到表的里面的數據。

創建一個Student控制器和視圖

實例化數據庫上下文:
private SchoolContext db = new SchoolContext();

獲取Student實例化數據:

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>
}

按快捷鍵CTRL+F5運行項目:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM