Getting Started with Entity Framework 6 Code First using MVC 5--Contoso 大学
在本教程中使用的软件版本
- Visual Studio 2013 年
- 4.5.NET
- 实体框架 (EntityFramework 6.1.0 NuGet 包) 6
- Windows Azure SDK 2.2(可选)
安装EntityFramework 6
从工具菜单上单击库的软件包管理器,然后单击程序包管理器控制台.
在软件包管理器控制台窗口中输入下面的命令:
Install-Package EntityFramework
该图像显示了 6.0.0 正在安装,但 NuGet 将安装最新的预发行版本的实体框架中,这起最新的更新的教程是 6.1.0。
在模型文件夹中创建一个名为Student.cs的类文件和模板代码替换为以下代码:
using System;
using System.Collections.Generic; 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属性将成为此类对应的数据库表的主键列。默认情况下,实体框架将解释命名的ID或类名ID作为主键的属性。
一般情况下,我们应该使用类名(表名)+ID作为主键,以保持与外键引用一致。其它字段直接用名词即可,无需添加首字母或类名。
Enrollments属性是一个导航属性。导航属性将保存与此实体相关的其他实体。在这种情况下,Student实体的Enrollments属性将保留所有的Enrollment实体的是该Student与实体相关的。换句话说,如果在数据库中的某一给定的Student行有两个相关的Enrollment行 (包含在其StudentID的外键列中的那个学生主键值的行),该Student实体的Enrollments导航属性将包含这两个Enrollment实体。 导航属性通常定义为virtual中,这样,他们可以利用某些实体框架功能,如延迟加载。(延迟加载稍后我将解释,读取相关数据教程稍后在本系列中)。 如果导航属性可以容纳多个实体 (如多对多或一对多的关系),其类型必须是一个列表,在其中可以添加、 删除和更新的如ICollection条目.
在模型文件夹中创建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; }
}
} EnrollmentID属性将是主要的关键 ;此实体使用的类名ID模式而不是ID本身正如你看到的Student实体中。通常你会选择一个模式,并使用它在您的数据模型整个。在这里,变化说明了您可以使用任一模式。在以后的教程中,你会你会看到如何使用ID没有classname的情况下容易,而在数据模型中实现继承。 Grade属性是枚举。问号后Grade类型声明指示Grade属性是可以为 null。为 null 的品位是不同从零级 — — null 意味着 a 级不已知或没尚未被分配。 StudentID属性是一个外键,并在相应的导航属性是Student。Enrollment实体是与一个Student实体、 关联,因此该属性只能容纳一个单一的Student实体 (不同的Student.Enrollments导航属性你看到较早前,可容纳多个Enrollment实体)。 CourseID属性是一个外键,并在相应的导航属性是Course。Enrollment实体是与一个Course实体相关联。 实体框架解释财产作为外键属性,如果它被命名为< 导航属性名称 >< 主键属性名称 > (例如,StudentID为Student导航属性因为Student实体的主键是ID)。外键属性还可以进行命名相同只是< 主键属性名称 > (例如, CourseID因为 Course实体的主键是CourseID).
使用枚举在使用支架时并不生成下拉列表,但会在客户端和服务器端自动验证输入的是否是枚举列出的对应的数值。
<input class="text-box single-line" data-val="true" data-val-number="The field Credits must be a number." data-val-range="字段 Credits 必须在 0 和 5 之间。" data-val-range-max="" data-val-range-min="" data-val-required="Credits 字段是必需的。" id="Credits" name="Credits" type="number" value="" />
创建的数据库上下文
在 ContosoUniversity 项目中创建一个文件夹,右键单击解决方案资源管理器中的项目和单击添加,然后单击新文件夹。名称的新文件夹DAL (对于数据访问层)。在该文件夹中创建一个新的类文件命名为SchoolContext.cs,和模板代码替换为以下代码:
using ContosoUniversity.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions; 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>语句,它会的工作方式相同。实体框架将包括这些隐式因为Student实体引用Enrollment实体和Enrollment实体引用Course实体。 指定连接字符串 连接字符串 (其中你会以后将添加到 Web.config 文件) 的名称在传递给构造函数。
public SchoolContext() : base("SchoolContext")
{
} 您还可以通过在连接字符串而不是一个存储在 Web.config 文件中的名称。有关用于指定数据库使用的选项的详细信息,请参见实体框架-连接和模型.
如果您不显式指定的连接字符串或一个名称,实体框架假定连接字符串的名称与类名称相同。在此示例中的默认连接字符串名称,然后将SchoolContext
,你要指定的显式相同。
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
上面一行用于指定表名是单数形式。一般情况下,我们建立的实体类都应该是单数,所以,上面一行可以省略。
数据库优先时,也应该使用单数名词作为表名,以与惯例保持一致。
设置 EF,用测试数据初始化数据库
实体框架可以自动创建 (或删除并重新创建) 为您在应用程序运行时的数据库。您可以指定应该这样每次运行应用程序或模型是与现有的数据库不同步时,才。您也可以编写Seed
的一种方法,实体框架将自动调用来填充它的测试数据创建数据库后。
默认行为是创建一个数据库,只有当它不存在 (和抛出异常,如果模型已更改,数据库已经存在)。在本节中,您将指定该数据库应被删除并重新创建模型发生变化时。删除数据库将导致所有数据的丢失。这通常是确定在开发期间,因为Seed
的方法将运行时数据库重新创建,并且将重新创建您的测试数据。但在生产中你一般不想失去你的所有数据,每次您需要更改数据库架构。稍后你会看到如何通过使用代码第一次迁移更改而不是删除和重新创建数据库的数据库架构处理模型更改。
Entity Framework数据库初始化四种策略
策略一:数据库不存在时重新创建数据库 Database.SetInitializer<testContext>(new CreateDatabaseIfNotExists<testContext>()); 策略二:每次启动应用程序时创建数据库 Database.SetInitializer<testContext>(new DropCreateDatabaseAlways<testContext>()); 策略三:模型更改时重新创建数据库 Database.SetInitializer<testContext>(new DropCreateDatabaseIfModelChanges<testContext>()); 策略四:从不创建数据库 Database.SetInitializer<testContext>(null); Entity Framework数据库初始化示例 using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Web.Models.Mapping; namespace Web.Models
{
public class testContext : DbContext
{
static testContext()
{
Database.SetInitializer<testContext>(null);
} public testContext()
: base("Name=testContext")
{
} public DbSet<Person> People { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonMap());
}
}
}
种子数据的添加,有两种方式,一种是在web.config中配置,一种是在Application_Start
中设置。
<entityFramework>
<contexts>
<context type="ContosoUniversity.DAL.SchoolContext, ContosoUniversity">
<databaseInitializer type="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity" />
</context>
</contexts>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
Application_Start
中设置
Database.SetInitializer<SchoolContext>(new SchoolInitializer());
一些放在global中的设置,修改后需要重新启动WEB站点。
DropCreateDatabaseIfModelChanges
初始值设定项
公约:
实体类名用作表名,应以单数形式体现。
实体属性名用于列名。
被命名为ID或类名+ID的实体属性将作为主键。
CRUD (创建、 读取、 更新、 删除)
延迟加载:如果需要循环延迟加载项进行绑定,可以预先将相关数据一起加载然后进行循环,以减少访问数据库的次数,消耗系统性能。
因为ID
是主键值,插入的行时,SQL Server 将自动设置,可删除从绑定属性的ID
。来自用户的输入并不设置的ID
值。
Security Note: The ValidateAntiForgeryToken
attribute helps prevent cross-site request forgery attacks. It requires a corresponding Html.AntiForgeryToken()
statement in the view, which you'll see later.
controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student)
view:
@Html.ValidationSummary(true)
Bind(Include = "LastName, FirstMidName, EnrollmentDate")]Student student
指定要绑定的属性列表可以防止客户端虚假提交无需从客户端获取的值,如经过计算后设置的值等。
Getting Started with Entity Framework 6 Code First using MVC 5--Contoso 大学的更多相关文章
- MVC2、MVC3、MVC4、MVC5之间的区别 以及Entity Framework 6 Code First using MVC 5官方介绍教程
现在MVC的技术日趋成熟,面对着不同版本的MVC大家不免有所迷惑 -- 它们之间有什么不同呢?下面我把我搜集的信息汇总一下,以便大家能更好的认识不同版本MVC的功能,也便于自己查阅. View Eng ...
- 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】
[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...
- Entity Framework 6 Code First新特性:支持存储过程
Entity Framework 6提供支持存储过程的新特性,本文具体演示Entity Framework 6 Code First的存储过程操作. Code First的插入/修改/删除存储过程 默 ...
- 创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表
创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表 创建数据模型类(POCO类) 在Models文件夹下添 ...
- AppBox升级进行时 - 拥抱Entity Framework的Code First开发模式
AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. 从Subsonic到Entity Framework Subsonic最早发布 ...
- Entity Framework 之 Code First
使用NuGet助您玩转代码生成数据————Entity Framework 之 Code First [前言] 如果是Code First老鸟或者对Entity Framework不感兴趣,就不用浪费 ...
- 在Entity Framework 中用 Code First 创建新的数据库
在Entity Framework 中用 Code First 创建新的数据库 (原文链接) 本文将逐步介绍怎样用Code First 创建新数据库,使用在代码中定义类和API中提供的特性(Attri ...
- Entity Framework Core Code First 项目实践
Entity Framework Core Code First 实践 任何一种技术的出现都是为了解决一系列特定的问题,只有了解了技术所要解决的关键问题,才能理解它的真正用途,之后,才能在实践中用好它 ...
- Entity Framework 6 Code First的简单使用和更新数据库结构
一.安装Entity Framework 6 在项目中右击选择“管理NuGet程序包",联机搜索Entity Framework,点击安装 二.配置数据库连接 在App.config中加入数 ...
随机推荐
- Intellij Idea 创建Web项目入门(一)
相关软件: Intellij Idea14:http://pan.baidu.com/s/1nu16VyD JDK7:http://pan.baidu.com/s/1dEstJ5f Tomcat(ap ...
- 在Ubuntu上为Android系统编写Linux内核驱动程序(老罗学习笔记1)
这里,我们不会为真实的硬件设备编写内核驱动程序.为了方便描述为Android系统编写内核驱动程序的过程,我们使用一个虚拟的硬件设备,这个设备只有一个4字节的寄存器,它可读可写.想起我们第一次学习程序语 ...
- trim合理和谐
今天早上,到公司,噩耗传来.上周的上线的功能出现问题,后台mis中有数据不能保存了. 经过紧张的查找,还是我的问题.有一个查重操作,在查重前,会比对新旧值,新值顺手trim了.旧值直接保存了. 在比较 ...
- IDEA 创建Web项目并在Tomcat中部署运行
IDEA 14.0.5 apache-tomcat-8.0.32 步骤:File->New Project,在Java列表中勾选Web Application(3.1),点击Next 建立web ...
- C++ STL之list容器的基本操作
由于list和vector同属于序列式容器,有很多相同的地方,而上一篇中已经写了vector,所以这一篇着重写list和vector的不同之处和特有之处. 特别注意的地方: (1)STL中迭代器容器中 ...
- C++中关于指针初始化和使用NULL的理解
1.严禁使用未被初始化的指针:C++创建指针的时候,只分配存储地址的内存,并不会分配存储数据的内存,所以指针可能指向任何位置. (1)使用解除运算符(*)之前,一定要对指针初始化,否则若声明的指针刚好 ...
- 域名服务器--DNS
.域名 .DNS.DNS 端口号 .DNS服务器 .域名解析过程及原理 .动态域名解析(DDNS)服务的原理 域名 域名是与主机名称一一对应的一个名字.使得人们可以通过ip的名字来访问ip,域名就是为 ...
- td内容自动换行 ,td超过宽度显示点点点… , td 使用 overflow:hidden 无效,英文 数字 不换行 撑破div容器
我们可以先给表格 table上 固定一个宽度 不让表格撑破 width: 747px; table-layout:fixed; 然后我们在td上加上如下样式 style="width:100 ...
- codevs 3290 华容道
HAHAHA BFS+SPFA. #include<iostream> #include<cstdio> #include<cstring> #include< ...
- cocos2d_x 问题汇总
1.生成so文件时,报“No rule to make target ”错误 解决方法:将.\xxx[appname]\proj.android\obj\local\armeabi\objs中的文件全 ...