[翻译][MVC 5 + EF 6] 1:创建数据模型
原文:Getting Started with Entity Framework 6 Code First using MVC 5
1.新建MVC项目:
2.修改Views\Shared\_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - Contoso University</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Contoso University", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
<div class="nav-collapse collapse">
<ul class="nav">
<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>
</div>
</div>
</div>
</div> <div class="container">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - Contoso University</p>
</footer>
</div> @Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
3.修改Views\Home\Index.cshtml:
@{
ViewBag.Title = "Home Page";
} <div class="jumbotron">
<h1>Contoso University</h1>
</div>
<div class="row">
<div class="col-md-4">
<h2>Welcome to Contoso University</h2>
<p>Contoso University is a sample application that
demonstrates how to use Entity Framework 6 in an
ASP.NET MVC 5 web application.</p>
</div>
<div class="col-md-4">
<h2>Build it from scratch</h2>
<p>You can build the application by following the steps in the tutorial series on the ASP.NET site.</p>
<p><a class="btn btn-default" href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/">See the tutorial »</a></p>
</div>
<div class="col-md-4">
<h2>Download it</h2>
<p>You can download the completed project from the Microsoft Code Gallery.</p>
<p><a class="btn btn-default" href="http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8">Download »</a></p>
</div>
</div>
4.安装EF:Tools --> NuGet Package Manager --> Package Manager Console
Install-Package EntityFramework
5.创建模型:
namespace ContosoUniversity.Models
{
public class Student
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; } public virtual ICollection<Enrollment> Enrollments { get; set; }
}
}
ID将会对应数据库中该类对应的数据表的主键列。默认情况下,EF会将名为ID或classnameID的属性当作主键。
Enrollments是导航属性。导航属性表示其他实体与本实体关联。
将导航属性定义为virtual,这样可以使用EF的一些功能,例如延迟加载。
如果导航属性为一对多或多对多关系,它的类型需要为集合类型,例如ICollection。
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; }
}
}
与Student中使用ID不同的是Enrollment中使用classnameID模式。一般情况下,我们在模型设计阶段只是用两种模式中的一种。但使用ID模式在数据模型中实现继承会更加容易。
Grade是枚举类型,问号表示其是可空类型。
StudentID是外键,对应导航属性Student。一个Enrollment实体紧对应一个Student实体。
如果一个属性名为导航属性的<导航属性名>+<主键属性名>,EF则会把它作为外键,例如StudentID为<Student>+<ID>。如果一个属性名为导航属性的<主键属性名>,EF也会把它作为外键,例如CourseID为Course的主键。
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; }
}
}
6.添加数据库上下文:
项目根目录添加名为DAL的文件夹,并在该文件夹下添加:
namespace ContosoUniversity.DAL
{
public class SchoolContext : DbContext
{ public SchoolContext() : base("SchoolContext")
{
} 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属性,则该实体就对应一个数据表。
上面的代码中可以去掉DbSet<Enrollment>和DbSet<Course>声明,EF会隐含的包含它们。因为Student引用了Enrollment,而Enrollment又引用了Course。
"SchoolContext"表示定义在Web.config中的数据库连接字符串。如果不使用Web.config的字符串,我们也可以传递一个完整的连接字符串。如果我们不指定连接字符串,EF会假定连接字符串的名字为上下文类的类名,如在本例中为"SchoolContext"。[更多请参考:Entity Framework - Connections and Models]
modelBuilder.Conventions.Remove代码的功能是在创建数据表时将表命名为单数形式,如Student、Enrollment和Course。如果不加此代码,数据表将会被命名为Students、Enrollments和Courses。这个可以根据个人命名习惯决定是否添加。
7.添加初始化数据:
EF会在程序运行时为我们自动创建(或删除重建)一个数据库。我们可以指定这个动作是在每次程序运行时执行还是在模型发生变化时执行。
EF默认的行为是在数据库不存在时新建一个数据库(如果一个数据库已经存在,则在模型发生改变的时候抛出异常)。在本节教程,我们指定数据库在模型发生变化时删除后重建。删除数据库会造成数据的丢失,这在开发环境下一般是可以接受的,但是在正式产品中,我们不希望在数据库模型发生改变的时候丢失数据。稍后我们将会看到如何使用代码优先迁移(Code First Migrations)来取代在数据库模型发生变化时删除后重建。
7.1.添加初始化数据类:
namespace ContosoUniversity.DAL
{
public class SchoolInitializer : DropCreateDatabaseIfModelChanges<SchoolContext>
{
protected override void Seed(SchoolContext context)
{
var students = new List<Student>
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
}; students.ForEach(s => context.Students.Add(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.Add(s));
context.SaveChanges();
var enrollments = new List<Enrollment>
{
new Enrollment{StudentID=,CourseID=,Grade=Grade.A},
new Enrollment{StudentID=,CourseID=,Grade=Grade.C},
new Enrollment{StudentID=,CourseID=,Grade=Grade.B},
new Enrollment{StudentID=,CourseID=,Grade=Grade.B},
new Enrollment{StudentID=,CourseID=,Grade=Grade.F},
new Enrollment{StudentID=,CourseID=,Grade=Grade.F},
new Enrollment{StudentID=,CourseID=},
new Enrollment{StudentID=,CourseID=,},
new Enrollment{StudentID=,CourseID=,Grade=Grade.F},
new Enrollment{StudentID=,CourseID=,Grade=Grade.C},
new Enrollment{StudentID=,CourseID=},
new Enrollment{StudentID=,CourseID=,Grade=Grade.A},
};
enrollments.ForEach(s => context.Enrollments.Add(s));
context.SaveChanges();
}
}
}
在seed方法中我们可以在添加完成所有的数据后再SaveChanges方法,但是上面的方式可以在插入数据异常时定位问题发生点。
7.2.添加初始化数据类的引用:
7.2.1.方法一(添加配置):
<entityFramework>
<contexts>
<context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
<databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
</context>
</contexts>
<!-- 其余省略 -->
</entityFramework>
这是为了告诉EF在新建数据库时调用插入初始化数据类。
context type指定上下文类和程序集,databaseInitializer type指定初始化数据类和程序集。如果想要取消插入初始化数据,可以在context添加属性:
<context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity" disableDatabaseInitialization="true">
7.2.2.方法二(Global.asax.cs的Application_Start
方法中添加):
Database.SetInitializer(new SchoolInitializer());
更多信息请查看:Understanding Database Initializers in Entity Framework Code First。
8.使用SQL Server Express LocalDB数据库:
添加配置:
<connectionStrings>
<add name="SchoolContext" connectionString="Data Source=(LocalDb)\v11.0;AttachDBFilename=|DataDirectory|\ContosoUniversity1.mdf;
Initial Catalog=ContosoUniversity1;Integrated Security=SSPI;" providerName="System.Data.SqlClient"/>
</connectionStrings>
此配置将会在项目的App_Data文件夹创建数据库文件。
如果我们没有添加连接字符串,EF会根据上下文类使用使用一个默认连接。
9.添加Student控制器和视图:
首先编译项目。
10.运行程序:
11.查看数据库:
其他的EF资源:ASP.NET Data Access - Recommended Resources。
[翻译][MVC 5 + EF 6] 1:创建数据模型的更多相关文章
- [翻译][MVC 5 + EF 6] 6:创建更复杂的数据模型
原文:Creating a More Complex Data Model for an ASP.NET MVC Application 前面的教程中,我们使用的是由三个实体组成的简单的数据模型.在本 ...
- [翻译][MVC 5 + EF 6] 7:加载相关数据
原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 1.延迟(Lazy)加载.预先(Eage ...
- [翻译][MVC 5 + EF 6] 12[完结]:高级场景
原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 1.执行原生SQL查询: EF Code First API ...
- [翻译][MVC 5 + EF 6] 11:实现继承
原文:Implementing Inheritance with the Entity Framework 6 in an ASP.NET MVC 5 Application 1.选择继承映射到数据库 ...
- [翻译][MVC 5 + EF 6] 10:处理并发
原文:Handling Concurrency with the Entity Framework 6 in an ASP.NET MVC 5 Application 1.并发冲突: 当一个用户编辑一 ...
- [翻译][MVC 5 + EF 6] 5:Code First数据库迁移与程序部署
原文:Code First Migrations and Deployment with the Entity Framework in an ASP.NET MVC Application 1.启用 ...
- [翻译][MVC 5 + EF 6] 9:异步和存储过程
原文:Async and Stored Procedures with the Entity Framework in an ASP.NET MVC Application 1.为什么使用异步代码: ...
- [翻译][MVC 5 + EF 6] 4:弹性连接和命令拦截
原文:Connection Resiliency and Command Interception with the Entity Framework in an ASP.NET MVC Applic ...
- [翻译][MVC 5 + EF 6] 3:排序、过滤、分页
原文:Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application 1.添加排序: 1. ...
随机推荐
- poj 1459 Power Network【建立超级源点,超级汇点】
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 25514 Accepted: 13287 D ...
- 用Quartus II 建立一个工程模板,以后新建工程时无需再配置参数
以前用Quartus II 每次新建工程时,都要设置工程名,选择工程路径,选择芯片型号等等,好麻烦呀!可不可以建一个工程模板,以后新建工程时直接改相应文件名就可以呀!后来我一琢磨,感觉也不是不可以.因 ...
- JBOSS实现RMI时注意的问题
使用JBOSS部署EJB服务后通过RMI访问报错: javax.naming.CommunicationException: Could not obtain connection to any of ...
- JQuery简单实现锚点链接的平滑滚动
在平时的项目中,我们经常需要一些特效链接,如果使效果进一步加强,我们可以使点击锚点链接平滑滚动到锚点,下面就来给大家讲解下如何使用jQuery来实现. 一般使用锚点来跳转到页面指定位置的时候,会生 ...
- Kinect for Windows SDK开发入门(15):进阶指引 下
Kinect for Windows SDK开发入门(十五):进阶指引 下 上一篇文章介绍了Kinect for Windows SDK进阶开发需要了解的一些内容,包括影像处理Coding4Fun K ...
- [转]非常好的vsftpd安装于配置
环境:CentOS 5.0 操作系统一.安装:1.安装Vsftpd服务相关部件:[root@KcentOS5 ~]# yum install vsftpd*Dependencies Resolved= ...
- js返回上一页方法区别
history.back(-1):直接返回当前页的上一页,数据全部消息,是个新页面 history.go(-1):也是返回当前页的上一页,不过表单里的数据全部还在
- [ES6] 23. Rest Parameters & Spread Parameters
Rest Parameters: In ES5, when you don't know how many paramters will be passed in, you can use argum ...
- mysqlbinlog 用法
操作命令: show binlog events in 'binlog.000016' limit 10; reset master 删除所有的二进制日志 flush logs 产生一个新的binl ...
- angular下H5上传图片(可多张上传)
最近做的项目中用到了angular下上传图片功能,在做的过程中遇到了许多问题,最终都得以解决 angular上传时和普通上传时过程差不多,只不过是要不一些东西转化为angular的东西. 1.ng-f ...