在本教程中使用的软件版本

安装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 大学的更多相关文章

  1. MVC2、MVC3、MVC4、MVC5之间的区别 以及Entity Framework 6 Code First using MVC 5官方介绍教程

    现在MVC的技术日趋成熟,面对着不同版本的MVC大家不免有所迷惑 -- 它们之间有什么不同呢?下面我把我搜集的信息汇总一下,以便大家能更好的认识不同版本MVC的功能,也便于自己查阅. View Eng ...

  2. 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例【转载自https://segmentfault.com/a/1190000004152660】

      [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例 本文我们来学习一下在Entity Framework中使用Cont ...

  3. Entity Framework 6 Code First新特性:支持存储过程

    Entity Framework 6提供支持存储过程的新特性,本文具体演示Entity Framework 6 Code First的存储过程操作. Code First的插入/修改/删除存储过程 默 ...

  4. 创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表

    创建ASP.NET Core MVC应用程序(3)-基于Entity Framework Core(Code First)创建MySQL数据库表 创建数据模型类(POCO类) 在Models文件夹下添 ...

  5. AppBox升级进行时 - 拥抱Entity Framework的Code First开发模式

    AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. 从Subsonic到Entity Framework Subsonic最早发布 ...

  6. Entity Framework 之 Code First

    使用NuGet助您玩转代码生成数据————Entity Framework 之 Code First [前言] 如果是Code First老鸟或者对Entity Framework不感兴趣,就不用浪费 ...

  7. 在Entity Framework 中用 Code First 创建新的数据库

    在Entity Framework 中用 Code First 创建新的数据库 (原文链接) 本文将逐步介绍怎样用Code First 创建新数据库,使用在代码中定义类和API中提供的特性(Attri ...

  8. Entity Framework Core Code First 项目实践

    Entity Framework Core Code First 实践 任何一种技术的出现都是为了解决一系列特定的问题,只有了解了技术所要解决的关键问题,才能理解它的真正用途,之后,才能在实践中用好它 ...

  9. Entity Framework 6 Code First的简单使用和更新数据库结构

    一.安装Entity Framework 6 在项目中右击选择“管理NuGet程序包",联机搜索Entity Framework,点击安装 二.配置数据库连接 在App.config中加入数 ...

随机推荐

  1. 转TerreyLee AJAX入门系列2——ScriptManager的理解总结

    ScriptManager的功能之一就是处理页面上局部更新,对于这点,我想大家都知道.但是他工作的原理到底是什么呢,这个暂且不从正面来回答. 我们这样想一下,目前能够真正实现局部刷新的就是js+xml ...

  2. 完美配置Tomcat的HTTPS

    Tomcat配置HTTPS的文章到处都有,过程也比较简单,随后文中会转一段过来. 但对于启用APR情况下报异常“java.lang.Exception: Connector attribute SSL ...

  3. sed替换单引号

    echo "Cfoo'barxml" | sed "s/'/::/g" |  sed 's/::/\\:/g' |  sed "s/:/'/g&quo ...

  4. java开发之匿名内部类,接口的使用

    下面的例子是Java.JDK7学习笔记上的 打算开发多人联机程序,对每个联机客户端,都会建立Client对象封装相关信息 1.Client.java public class Client { pri ...

  5. 面试题_1_to_16_多线程、并发及线程的基础问题

    多线程.并发及线程的基础问题 1)Java 中能创建 volatile 数组吗?能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组.我的意思是,如果改变引 ...

  6. org.tigris.subversion.javahl.ClientException: Attempted to lock an already-locked dir异常解决方法

    myeclipse用svn提交的时候报错: Attempted to lock an already-locked dir svn: Working copy 'D:/Program Files/My ...

  7. 一个简单的ORM制作(SQL帮助类)

    一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...

  8. 在Windows下利用php自带的mail函数发邮件

    这几天看<Head First PHP & MySQL>,里面有发邮件的例子是用系统自带的mail函数发送的,自己照书上写的试了一直不成功,后来终于在网上找到解决方案,现在总结下. ...

  9. UVa 10341 (二分求根) Solve It

    很水的一道题,因为你发现这个函数是单调递减的,所以二分法求出函数的根即可. #include <cstdio> #include <cmath> //using namespa ...

  10. eval绑定decimal数据后,如何去掉后面没有意义的0?

    假如有个数字是 25.00 就应该只显示 25   ,而如果是25.3 则还是显示 25.3   Score.ToString("g0")  这样就可以去掉 decimal 后面多 ...