EF5&MVC4 學習一、建立新的Contoso University Application,並建立Model Class 生成對應的database

參考:http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/creating-an-entity-framework-data-model-for-an-asp-net-mvc-applicationcss

Create The Contoso University Web Applicationhtml

Contoso University sample web applicatioin 是一個使用MVC4 & EF5 & VS2012建立的Sample網站。網站功能包括:學生入學,課程選擇,做業佈置。這一系列的教程會教咱們如何創建這個網站。jquery

 

Code First web

在Entiry Framework中,咱們有三種處理數據的方法:Database First,Model First,and Code First.這個教程中,咱們使用Code First。關於這三種之間的差異以及具體該選擇哪一種,能夠參考Entity Framework Development Workflows數據庫

 

The Contoso University Web Applicationmvc

功能:用戶能夠查看,更新學生、課程、教師信息。app

這個Application的UI頁面,是系統自動生成的Template。因此咱們能夠關注於怎麼去用Entity Framework.以後咱們再用Kendo UI去更新咱們的UI。asp.net

 

準備(Prerequisits): Windows Azure SDK http://go.microsoft.com/fwlink/?LinkId=254364ide

 

一,建立一個MVC WEB Application學習

Create a new project named 「ContosoUniversity」,Using .NET Framework 4.5

 

網站樣式設置(Set Up The Site Style

咱們會對網站的site menu,layout和home page作出一些更新

Views\Shared\_Layout.cshtml:更改母版頁的標題,增長一些鏈接

<!DOCTYPE html>
<html lang="zh">
    <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <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("首頁", "Index", "Home")</li>
                            <li>@Html.ActionLink("關於", "About", "Home")</li>
                            <li>@Html.ActionLink("學生", "Student", "Home")</li>
                             <li>@Html.ActionLink("課程", "Course", "Home")</li>
                             <li>@Html.ActionLink("教師", "Instructors", "Home")</li>
                            <li>@Html.ActionLink("部門", "Departments", "Home")</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>
View Code

Views\Home\Index.cshtml:只保留如下這些:

Controllers\HomeController.cs更改ViewBage.Message的內容:

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

            return View();
        }

Ctrl+F5運行:

 

二,爲Contoso University application 建立實體數據模型(Entity Data Model)

Model 中添加Entity Class:

1,添加Student.cs類: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

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> Entrollments { get; set; }
    }
}
View Code

2,添加Course.cs類

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

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

    }
}
View Code

3,添加Enrollment.cs類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

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

 

三,建立數據上下文類(Create the Database Context

 

數據庫上下文類是Model 中的實體數據模型(Data Model)Entity Framework 之間的橋樑

Database context class類繼承自System.Data.Entity.DbContext 類,這裏面你須要指明哪些實體包含在data model 中。你一樣能夠自定義某些特定的Entity Framework behavior. 這個Project DbContext的類名爲SchoolContext

 添加DAL文件夾,而後添加SchoolContext類:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

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

 

DbContext類爲每個實體集(entity set)建立了一個DbSet屬性

每個實體集對應database中的一張table,每個實體對應

OnModelCreating方法中的modelBuilder.Conventions.Remove 防止表中的數據以複數(Students,Courses,Enrollments)命名。

 

四,SQL Server Express LocalDB

.mdf爲後綴的database文件,是一個單獨的文件放置於項目中的App_Data文件夾中。LocalDB不被推薦使用在web application中由於它不會和IIS一塊兒工做。VS2012以及之後的版本中,LocalDB被默認安裝在VS中。

若是你是用.mdf存貯數據的話,須要更新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" />

默認狀況下,Entiry Framework 會在webconfig中尋找和類名DbContext同名的鏈接字符串(這裏是SchoolContext),鏈接字符串就會指定APP_Data中一個命名爲ContosoUniversity.mdf的數據文件

 

若是你不手動在webconfig中添加這個鏈接字符串,Entity  Framework就會自動給你添加一個鏈接字符串,可是這個database文件不會再App_Data文件中。

 

ConnectionStrings 中包含有名字爲DefaultConnection的默認的字符串鏈接,這個鏈接是用於Membership database的。在這個教程中咱們暫時不會用到membership database. 這兩種鏈接的不一樣之處就是數據庫名稱(database name)和屬性值(attribute value).

 

5、設置並執行Code First Migration . Set up and Execute a Code First Migration

 

在咱們開始開發項目的時候,咱們須要頻繁的更新Data Mode中的實體類(entity class ),每一次更新之後,Model 中的字段就和database中的字段不一致了。

因此咱們須要配置Entity Framework 來自動drop 或者re-create database來和model 中的實體類同步。這樣drop的方法來更新,在開發中咱們用的都是測試數據不會有什麼問題,可是一旦部署到正式環境,咱們就不能用這種方法去同步modedatabase了。 Code FirstMigrations功能可讓咱們更新數據庫結果,而且不用去drop re-create database

 

5.1 Enable Code First Migrations

1,Package Manager Console:

 

2,輸入命令:PM>enable-migrations -contexttypename SchoolContext

啓用成功,而且建立了Migrations文件夾以及Configurations.cs文件

 

database在被created的時候以及每一次從Model中進行同步更新的時候,Configuration.cs中的Seed方法就會被調用。

Seed方法可讓咱們可以在Code First建立或者更新database之後,插入測試數據。

 

5.2 Set up Seed Method

namespace ContosoUniversity.Migrations
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    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)
        {
            //  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" }
            //    );
            //

            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();

        }
    }
}
View Code

Seed 方法,在Code First Migrations 建立database以及每一次從上次的migrations 進行update database的時候執行。Seed方法的目的是可讓你在application 讀取database數據以前tablesinsert data.

 

Seed方法中添加的數據大部分是測試用的,或者是一些發佈到正式環境也必須有的數據,例如部門信息等,這樣咱們在開發的時候就不用每一次都手動的進行添加數據。

 

1,更新Seed方法,這樣程式運行的時候就會加載這些測試數據

 

Seed方法把database context對象做爲輸入參數,而後添加新的實體到database中。對於每個實體類型來講,code首先建立了實體的集合(list),而後把他們添加到對應的DbSet屬性中,而後用SaveChange()方法保存到database.

 

AddOrUpdate方法執行了一個插入更新的動做。每一次Mirgraiton的時候Seed方法都會執行,它會把開發測試過程當中的更新重寫到database中。

 

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

 

AddOrUpate中的第一個參數,指定根據這個參數的屬性去檢查實體數據是否存在。在測試的Student data中,咱們用LastName,由於在List的列表中,LastName是惟一的。

若是咱們添加一條LastName重複名稱的student.當你進行database migrations的時候就會報出下面的錯誤:

Sequence contains more than one element

   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方法中添加Enrollment Entities的時候,並無用到AddOrUpdate方法。

而是用了Add,這個方法會檢查enrollment 實體數據是否存在,不存在的話加入一條新的數據,若是存在不會對其進行更新。Foreach循環遍歷 Enrollment中的每個實體,在你第一次update database的時候,這些實體就會被添加到database中。

 

2.Ctrl+Shift+B重建解決方案:

 

5.3 Create and Execute the First Migration建立並執行遷移

1Package Manager Console中輸入命令建立最開始的遷移,並更新

1.  PM>add-migration InitialCreate
2.  PM>update-database

 

add-migration 命令添加了Migrations文件夾,而且包含遷移類文件,遷移類生成了database. InitialCreate是本身定義的參數名字。

遷移類中的Up方法,建立了和Model Class中實體集合(entity sets)對應的database tables. Down方法是刪除這些實體。Migrations調用Up方法去執行data model 中的改變。當你Update-database的時候,Migrations調用了Down方法。

 

update-database 先調用Up方法建立數據庫,而後調用Seed方法把數據填充到數據庫中。

 

完成以上,咱們便在App_Data中建立了一個.mdf後綴的SQL Server 數據庫文件。.mdf文件的名字是咱們在webconfig的鏈接字符串中定義的。

咱們看到資料庫和.mdf文件:

 

 

 

 

6、Creating a Student Controller and Views

 

 

總結:

 

咱們建立了一個簡單的application。接下來,咱們會學習如何執行CRUD(create,read,update,delete)

 

 

C#基礎:

 

相關文章
相關標籤/搜索