Entity Framework 4.x 进行代码优先 (Code-First) 开发

原文地址:http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspxcss

Entity Framework 是一个位于命名空间 System.Data.Entity 中的数据访问库。NET4 对 Entity Framework 进行了大量改进。web

当 Entity Framework 第一次在 .NET SP1 被引入的时候,开发人员对这个版本提交了大量的反馈,反映他们认为第一个版本不完备的地方。SQL 开发团队认真听取了这些反馈,在 .NET4 中,解决了这些问题。正则表达式

在 EF4 中的重要改进包括:数据库

  • POCO 支持: 如今你能够定义实体,不须要基类或者数据持久化的标签.
  • Lazy Loading 支持: 你能够在之后加载一个模型的子对象,而不须要提早加载。.
  • N-Tier Support and Self-Tracking Entities: 处理跨层的实体访问或者无状态的  web 调用.
  • Better SQL Generation and SPROC support: EF4 生成更好的 SQL, 包括更好地与存储过程集成
  • Automatic Pluralization Support: EF4 包括自动的表支持 (例如 Categories->Category).
  • Improved Testability: EF4 的对象如今能够更加方便地使用接口.
  • Improved LINQ Operator Support: EF4 如今彻底支持 LINQ.

Visual Studio 2010 还包括一个功能更加丰富的 EF 设计器和工具支持。在 VS2010 中的 EF 设计器既支持数据库优先 (database first) 的开发风格,从一个已经存在的数据库开始设计模型,也支持模型优先 (model first) 的开发风格,首先设计数据模型,而后经过模型来生成数据库的架构。浏览器

使用 EF 进行代码优先的开发

为了支持以设计为中心的开发流程,EF4 还更多地支持以代码为中心 (code-centric) ,咱们称为代码优先的开发,代码优先的开发支持更加优美的开发流程,它容许你:服务器

  • 在不使用设计器或者定义一个 XML 映射文件的状况下进行开发。
  • 容许编写简单的模型对象POCO (plain old classes),而不须要基类。
  • 经过"约定优于配置",使得数据库持久层不须要任何的配置
  • 也能够覆盖"约定优于配置",经过流畅的 API 来彻底定制持层的映射。

EF 代码优先的开发如今经过就能够支持,如今刚刚发布 4.1 的 RC 版,你能够经过这里下载架构

它与 VS2010 一块儿工做,你能够在任何 .NET 4 的项目中使用,包括 ASP.NET Web Forms 项目和  ASP.NET MVC 项目。asp.net

教程:使用代码优先来建立 NerdDinner

前年,我编写了一个 MVC1.0 的 教程,这个示例发布在这里和书中,这个教程建立一个称为 NerdDinner 的简单应用,能够帮助人们简单地在线组织、安排和答复晚餐。工具

NerdDinner 教程使用数据库优先的方式进行设计。ui

下面我将演示如何经过代码优先的方式来完成这个目标,使用 EF4来建立 NerdDinner 的模型层和数据库架构,而后使用 ASP.NET MVC 构建一个 CRUD 的应用。

咱们将会一步一步地建立这个应用,整个项目的下载连接在文章的后面。

第一步:建立一个空的 ASP.NET MVC2 应用

咱们将经过在 VS2010 中建立一个空间的 ASP.NET MVC3 应用开始,选择 File -> New Project,使用 ASP.NET MVC2 Empty Web Application 模板。

建立完成以后的项目以下:

下一步,咱们将会定义咱们的 NerdDinner 模型,用来表示程序中使用的数据,同时也包括集成的验证和业务规则在内的逻辑。模型是 MVC 应用的心脏。

第二步:建立模型

假定咱们尚未定义数据库,咱们彻底从头开建立咱们的 NerdDinner 应用。

咱们不须要从数据库开始

在代码优先的开发流程中,咱们不须要经过建立一个数据库或者架构开始,相反,咱们经过编写标准的 .NET 类定义域中的对象来开始,不须要担忧任何复杂的持久层逻辑。

建立模型类

NerdDinner 是一个很小的应用,咱们的数据很是简单,咱们但愿定义和存储 "晚餐" 来表明人们将会参加的事件,咱们也但愿可以定义和存储 "答复"(RSVP) 来表示人们的答复。这能够用来跟踪参与的特定晚餐。

让咱们建立两个类 Dinner 和 RSVP 来表示这些内容,咱们将会经过在项目中增长新的类来完成。

上面的 Dinner 和 RSVP 模型类是简单和从前的 CLR 对象,一般称为 POCO,它们不须要从任何基类派生或者实现任何接口,属性抛出了类型是标准的 .NET 数据类型,没有数据持久层的标签或者代码附加在里面。

定义模型类不须要将它们绑定在特定的数据库上,特定的数据库 API 上,或者数据库架构的实现上,这是真正强大的能力,使得咱们能够更加灵活地进行数据访问,容许咱们关注在应用的逻辑上而不须要担忧持久层的实现。同时也使 得咱们能够灵活地改变数据库的架构或者存储的实现,很是流畅而不须要改写任何咱们的模型对象,或者访问它们的代码。

建立上下文对象来处理数据库的持久化

如今咱们已经定义了咱们的两个 POCO 模型类,下面咱们建立一个类来来完成从数据库中获取/持久化 Dinner 和 RSVP 实例。

咱们命名这个类为 NerdDinners。它派生自 DbContext 基类,有两个公共的属性,一个暴露咱们的 Dinner 对象,一个暴露咱们的 RSVP 对象。

上面用到的 DbContext 和 DbSet 类是 EF4 代码优先库的一部分,你须要添加对EntityFramework 程序集的引用。同时,你还须要在类文件的开始部分增长 using System.Data.Entity 命名空间的代码。

这就是全部你须要编写的!

上面的三个类包含项目中基本的模型和数据持久层全部须要的代码,甚至咱们不须要配置任何额外的数据库架构映射信息,或者运行任何的工具,也不须要编辑任何的 xml 文件,也不须要经过任何的设计器来开始使用咱们的类。

基于持久层映射的约定

咱们不须要任何额外的代码,也不须要建立任何 xml 文件,也不须要工具来影射咱们的模型类与数据库,你可能想,这怎么可能呢?

默认状况下,EF 代码优先支持约定优于配置的目标,你能够经过映射约定来代替显式的配置参数,若是须要的话,你能够提供自定义的映射规则来覆盖默认的映射规则,可是,若是 你使用默认的映射规则,你会发现你须要编写的代码真的很是少,90% 的状况下,你不须要任何额外的代码或者配置。

在咱们上面的例子中,NerdDinners 上下文类将会默认的映射它的 Dinners 和 RSVPs 属性到数据库中的 Dinners 和 RSVPs 表,在 Dinners 表中的每一行将会映射到 Dinner 类的一个对象,与此相似,RSVP s 中的每一行将会映射到 RSVP 类的一个对象,Dinner 和 RSVP 类中的属性将会映射到 Disnners 和 RSVPs 表的列。

EF 支持的其余的约定规则包括基于一般的命名模式自动识别主键和外键,例如 Id 或者 DinnerId 属性将会被识别为主键,EF 还支持智能地识别模型对象之间的关系,EF 团队有一篇博文讨论默认的约定规则。点击这里

使用咱们模型的示例

下面咱们看一下常见的使用场景。

使用 LINQ 进行查询

咱们使用下面的代码从数据库中查询数据。

咱们也能够在 LINQ 中使用 Dinners 和 RSVPs 的关系,注意,下面的 where 子句过滤 RSVP 大于 0 的晚餐。

在上面的查询中,咱们查询至少有一个答复的晚餐。

获取单个实例

咱们可使用 LINQ 的 Single() 方法,经过传递一个 Lambda 表达式来获取单个的 Dinner 实例。

另外,咱们也能够经过 EF 支持的 Find() 方法来基于 ID 获取实例。

增长一个新的晚餐

下面的代码演示如何建立一个新的晚餐,而后写入数据库中,咱们须要的就是 new 一个 Dinner 对象,设置属性,而后增长到 NerdDinners 上下文对象的 Dinners 属性的集合中,NerdDinner 上下文对象支持工做单元的模式,容许增长多个对象。而后,调用 SaveChanges() 方法来做为一个简单的原子事务操做持久化全部的修改到数据库中。

更新晚餐

更新对象的属性,而后保存到数据库中。

第三步:建立 ASP.NET MVC 的控制器使用咱们的模型

下面咱们在一个更加复杂的场景下使用咱们的模型。咱们使用控制器来实现发布一个晚餐的列表,而且容许用户增长新的项目。

在 Controller 文件夹上右键,选择 Add -> Controller 菜单,将咱们的控制器命名为 HomeController。

而后,增长 Action 方法。

Index Action 方法获取并生成一个晚餐的列表。

Create Action 方法容许用户增长新的晚餐,当用户直接访问地址 /Home/Create 的时候,系统提供一个空白的晚餐表单以供填写。第二个 Create 方法处理 Post 请求,将晚餐保存到数据库中,若是有验证没有经过,将会向用户返回错误提示信息。

为控制器增长视图

下一步,咱们增长两个视图,一个 Index ,一个 Create.

在 Action 方法上点击右键,选择 Add View 菜单,在 Add View 对话框中,咱们使用强类型的视图,传递 Dinner 的 IEnumerable 列表。

而后,选择 Add, 将会建立 Index.aspx 视图文件,在其中增长下面的代码,建立一个无符号的列表来显示晚餐。

而后,增长 Create 视图,传递 Dinner 对象。

而后,在其中定义表单。

如今,咱们实现了全部须要的功能,能够显示晚餐,而且增长项目。

第四步:数据库

咱们已经完成了咱们的代码,如今,运行一下。

可是,数据库呢?

咱们尚未数据库,由于代码优先的工做方式并不须要一个已经存在的数据库。

可是,当咱们实际运行咱们程序的时候,咱们仍是须要一个数据库来保存咱们的晚餐和回复对象。咱们能够经过下面的两种方式之一建立数据库。

  • 使用数据库的工具,手动建立和定义数据库
  • 经过 EF Code-First 库,根据咱们的模型自动建立。

第二种方式很是酷,咱们下面使用这种方式。

在开始以前,咱们先配置数据库链接串,来讲明数据库的位置,咱们的配置以下所示:

默认状况下,当建立一个 DbContext 类的时候,EF Code-First 库将会寻找与类名相同的数据库链接串,由于咱们的类名为 NerdDinners ,因此,默认状况下,将会使用名为 NerdDinners 的数据库链接串。

SQL CE4 的优点

配合 EF Code-First 你可使用许多种不一样的数据库,例如 SQL Server, SQL Express,MySQL 等等。

SQL CE4 是一个轻量级的基于文件的数据库,免费,设置简单,能够嵌入在 ASP.NET 应用中,它支持低费用的寄宿环境,也能够容易地合并到 SQL Server 中。

在定义和生成模型层的阶段,SQL CE 能够快速和从新建立你的数据库,咱们将使用 SQL CE4 来开发 NerdDinner 应用。之后,在产品发布的时候,经过改变数据库链接串,来使用 SQL Express 或者 SQL Server,不须要修改一行程序代码。

上面的链接串指向 NerdDinners.sdf 文件,使用 SQL CE4 数据库提供器,你须要安装 SQL CE4,能够经过独立安装:独立的 SQL CE 安装器 或者经过安装 WebMatrix, SQL CE4 很小,只须要几秒的时间来安装。

重要提示:上面的链接串指示在 \DataDirectory\ 文件夹下建立 NerdDinners.sdf 文件,在 ASP.NET 程序中, 就是在 App_Data 文件下,默认的 Empty ASP.NET MVC Web Application 没有建立这个目录,你能够经过在项目上右键菜单中 Add-> ASP.NET Folder -> App_Data 来建立。

自动建立数据架构

EF Code-First 支持经过模型类自动建立数据库的架构,不须要手动来完成这些操做。

若是数据库链接串指向的数据库或者文件不存在的时候,默认将会自动进行操做,你甚至不须要任何操做就能够。

在咱们的项目中,按  F5 运行应用,你将会看到以下的界面。

经过调用 HomeController 中的 Index 方法,咱们实例化而且访问 NerdDinners 上下文对象来获取全部的晚餐列表,由于数据库链接串指向的 NerdDinners.sdf 并不存在,EF Code-First 将会自动建立它,而后使用 NerdDinners 来建立数据库的架构。

在 VS 的资源管理中,点击 Show all Files 图标,而后点击 Refresh 按钮就能够看到这个数据库文件。

下面是数据库中的表

Dinners 表的结构以下。DinnerId 列被配置为主键,并设为标识列。

RSVP 表的结构以下,RSVPId 列为主键和标识列。

还建立了一个一对多的主外键关联,由于咱们的 Dinners 有一个名为 RSVPs 的 ICollection<RSVP> 类型的属性,在 RSVP 类中有一个 Dinner 的属性。

建立一个晚餐

点击 Create New Dinner 连接,将会导航到 Create 页面。

 

 点击 Create 按钮,咱们新的晚餐将会被保存到数据库中,屡次重复以后,咱们可能会看到下面的列表。

 第五步:修改咱们的模型

咱们继续重构咱们的程序,EF Code-First 包含许多不错的开发功能来协调开发数据库。

为模型增长新的属性

下面咱们作一些简单的修改,增长一个名为 Country 的属性。

如今,按 F5 运行程序,将会看到下面的错误信息。

 这是由于咱们修改了 Dinner 类,如今咱们的模型对象再也不与数据表同步了,

当 EF 自动为你建立数据库的时候,默认状况下,会在数据库中增长一个 EdmMetadata 的表来跟踪自动建立的数据库架构。

当 EF 检测到你的模型对象与数据库不一致的时候就会抛出异常信息。

从新与数据库同步咱们的模型类

 有几种方式来同步咱们的模型对和数据库

  1. 手动更新咱们的数据库架构
  2. 手动删除咱们的数据库文件,而后从新运行程序来从新建立
  3. 启用 EF Code-First 功能来容许它在修改模型以后自动更新咱们的数据库

让咱们看一下最后一种方式。

RecreateDatabaseIfModelChanges 功能

EF Code-First 包含一个开发时的功能支持在你修改模型类以后,自动重建你的的数据库。当启用以后,任何的模型修改都回致使 EF 自动重建数据库。不须要手工步骤。

在开始开发的时候,这是一个颇有用的功能,使得你自由和灵活地重构和从新组织你的模型代码,而不须要任何手工操做来同步数据库的架构。尤为是与 SQL CE4 配合的时候更加好,由于这是基于文件的数据库,能够在几秒以内被删除和重建。这能够难以置信地加速开发流程。

启用这个功能的简单方式就是在Global.asax 文件的 Application_Start 中增长 Database.SetInitializer() 方法的调用。

 如今,咱们从新运行程序,不会看到错误信息,EF 已经从新建立了数据库。

 在建立数据库的时候初始化数据

你可能注意到,从新建立的数据库是空的,咱们丢掉了原来加入的数据。RecreateDatabaseIfModelChanges 行为没有合并咱们的数据,它被设计用在开发场景下,快速、自动地为你更新数据库。

你能够在建立数据库的时候播种一些数据,下面的代码中,我建立了两个晚餐,而后加入到数据库中。

 在 Database.Initializer() 中咱们调用这个类。

 如今,任什么时候候咱们从新建立的数据库中,将会已经增长了两条数据。

 第六步:增长验证规则

咱们已经建立了一个简单的应用。

如今的问题是,咱们没有任何的验证规则来保证填入的数据是正确的,下面咱们解决这个问题。

使用 DataAnnotations 增长验证规则

在 ASP.NET MVC 中,验证规则一般基于模型,这使得能够在单一位置维护它们。强制在任何的控制器和视图中使用这些规则。

ASP.NET MVC2 包含使用 System.ComponetModel.DataAnnotations 库中的验证规则,这容许咱们使用标签来标注验证规则。

回到 Dinner 类定义验证规则。

 [Required] 验证标签标识必须提供的属性,[StringLength] 验证标签标识字符串的最大长度,[RegularExpression] 标签容许指定一个正则表达式进行验证,这是是验证一个电子邮件地址。

每个标签都支持 ErrorMessages 属性,容许指定一个验证失败状况下的错误信息,可使硬编码的字符串,也能够来自资源,能够方便地进行本地化。

引用一些 CSS 和 JavaScript 脚本

最后一步咱们回到视图模板,增长 Site.css 的连接,还有两个脚本的连接,最后,在 form 元素呈现以前,还要增长一行调用 Html.EnableClientValidation() 的方法调用。

 这些修改将会包含错误信息,并应用到客户端以及服务器端的验证上。

运行程序

让咱们再次运行程序,建立一个新的晚餐,在没有填充任何内容的状况下,直接点击 Create 按钮,如今,咱们的验证信息将会出如今浏览器上。

 由于启用了客户端验证,因此,验证信息实时出如今页面上。

 注意到标题长度大于 20 个字符的时候,StringLength 验证规则生效,而 HostedBy 将经过正则表达式验证电子邮件地址。

验证规则同时做用于客户端和服务器端,这使得咱们能够简单清楚地保护咱们的应用。

EF 4.1 Release Candidate 的下载地址

相关文章
相关标签/搜索