参考: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-application

Create The Contoso University Web Application

Contoso University sample web applicatioin 是一个使用MVC4 & EF5 & VS2012创建的Sample网站。网站功能包括:学生入学,课程选择,作业布置。这一系列的教程会教我们如何建立这个网站。

Code First

在Entiry Framework中,我们有三种处理数据的方法:Database First,Model First,and Code First.这个教程中,我们使用Code First。关于这三种之间的差别以及具体该选择哪种,可以参考Entity Framework Development Workflows

The Contoso University Web Application

功能:用户可以查看,更新学生、课程、教师信息。

这个Application的UI页面,是系统自动生成的Template。所以我们可以关注于怎么去用Entity Framework.之后我们再用Kendo UI去更新我们的UI。

准备(Prerequisits): Windows Azure SDK http://go.microsoft.com/fwlink/?LinkId=254364

 

一,创建一个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>

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

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

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

三,创建数据上下文类(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; }
}
}

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).

五、设置并执行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 = , Title = "Chemistry", Credits = , },
new Course {CourseID = , Title = "Microeconomics", Credits = , },
new Course {CourseID = , Title = "Macroeconomics", Credits = , },
new Course {CourseID = , Title = "Calculus", Credits = , },
new Course {CourseID = , Title = "Trigonometry", Credits = , },
new Course {CourseID = , Title = "Composition", Credits = , },
new Course {CourseID = , Title = "Literature", Credits = , } };
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 方法,在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文件:

六、Creating a Student Controller and Views

 

总结:

 

我们创建了一个简单的application。接下来,我们会学习如何执行CRUD(create,read,update,delete)

 

 

C#基础:

EF5&MVC4 学习1、创建新的Contoso University Application,并创建Model Class 生成对应的database的更多相关文章

  1. ubuntu18.04安装mysql以及重置密码创建新用户

    1.安装mysqlsudo apt-get install mysql-serversudo apt-get install mysql-clientsudo apt-get install libm ...

  2. Oracle安装后忘记用户名或密码+创建新登陆用户

    新安装的Oracle11g,不料在使用的时候没记住安装时的用户名和密码. 不用担心,打开sqlplus. 按如下步骤,新建一个登陆用户: 第一步:以sys登陆  sys/密码 as sysdba  此 ...

  3. Django 创建新项目后要完成的几个步骤

    首先,在过一遍创建新项目的步骤: -创建一个新项目 -建了数据库后要确定自己是用 mysql数据库  还是用 sqlite3数据库 -如果是mysql数据库,那一堆配置 -如果是sqlite3数据库, ...

  4. TestCase--网站创建新用户管理模块

    对于web测试,用户权限管理模块是必测的一个点,所以今天就来总结一下创建新用户管理模块的测试用例 参考图如下: 测试用例设计如下: 一.功能测试 1.  什么都不输入,单击“立即提交”,页面是否有提示 ...

  5. (转)Qt Model/View 学习笔记 (四)——创建新的Models

    创建新的Models 介绍 model/view组件之间功能的分离,允许创建model利用现成的views.这也可以使用标准的功能 图形用户接口组件像QListView,QTableView和QTre ...

  6. odoo学习:创建新数据库及修改数据库内容

    1.切换到odoo用户 su - odoo -s /bin/bash 2. 创建新数据库 createdb v8dev 3. 初始化数据库,并配置odoo数据模式 chmod +x odoo: odo ...

  7. linux进程学习-创建新进程

    init进程将系统启动后,init将成为此后所有进程的祖先,此后的进程都是直接或间接从init进程“复制”而来.完成该“复制”功能的函数有fork()和clone()等. 一个进程(父进程)调用for ...

  8. MySQL学习(一)——创建新用户、数据库、授权

    一.创建用户 1.登录mysql mysql -u root -p 2.创建本地用户>/font> use mysql; //选择mysql数据库 create user 'test'@' ...

  9. OFBiz进阶之HelloWorld(五)创建新实体

    参考文档 https://cwiki.apache.org/confluence/display/OFBIZ/OFBiz+Tutorial+-+A+Beginners+Development+Guid ...

随机推荐

  1. 迁移到MariaDB galera

    迁移到MariaDB galera [已注销] [已注销] -- :: [安装] ====== https://downloads.mariadb.org/mariadb/repositories/ ...

  2. 在iptables防火墙下开启vsftpd的端口

    在开启vsftpd端口后发现用客户端工具能登陆,但无法浏览文件和新建文件.此时看了一下ftp的协议,发现ftp有主动模式和被动模式.在服务端开21端口是让客户端进来,并没有出去的端口,还在服务端开启出 ...

  3. Python Tricks 若干

    赵斌 - APRIL 29, 2015 在 python 代码中可以看到一些常见的 trick,在这里做一个简单的小结. json 字符串格式化 在开发 web 应用的时候经常会用到 json 字符串 ...

  4. JavaScript面向对象+Array的用法及字符串组合+动态建立锚点

    脚本部分: function school(sName,sDddress,sPhone,sMail) { this.SName = sName; this.SAddress = sDddress; t ...

  5. Spark源码分析(三)-TaskScheduler创建

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3879151.html 在SparkContext创建过程中会调用createTaskScheduler函 ...

  6. Android addRule()

    布局中有很多特殊的属性,通常在载入布局之前,在相关的xml文件中进行静态设置即可. 但是,在有些情况下,我们需要动态设置布局的属性,在不同的条件下设置不同的布局排列方式,这时候就需要用到 Relati ...

  7. Friends(老友记)(六人行)相关资源

    迅雷账号:104303980 老友记 Friends 的所有种子: http://www.ttmeiju.com/meiju/Friends.html 老友记(friends)高清(720p)+字幕 ...

  8. 脉络清晰的BP神经网络讲解,赞

    学习是神经网络一种最重要也最令人注目的特点.在神经网络的发展进程中,学习算法的研究有着十分重要的地位.目前,人们所提出的神经网络模型都是和学习算 法相应的.所以,有时人们并不去祈求对模型和算法进行严格 ...

  9. JAVASCRIPT和JQUERY判断浏览器信息总汇(备忘)

    <script type="text/javascript">        //jquery判断浏览器信息        $(function(){          ...

  10. .net Windows服务程序和安装程序制作图解 及 VS 2010创建、安装、调试 windows服务(windows service)

    .net Windows服务程序和安装程序制作 最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作 ...