原文名称:EF Code First and Data Scaffolding with the ASP.NET MVC 3 Tools Update
我们刚刚发布了 ASP.NET MVC3 的工具更新,安装地址:http://asp.net/mvc
在今天的博客中,我将详细介绍这次更新带来的两个酷的特性:
- 对 EF4.1 的内置支持,包括 Code First
- 通过 Visual Studio 支持内建的数据脚手架支持,这可以使你迅速创建数据驱动的站点。
这两个特征对 Web 应用程序提供了强大的支持。
我们将要创建的目标
为了帮助说明如何使用这两个特性,我们将创建一个简单的数据驱动站点,这个站点可以列出我们的产品。
下面是创建或者编辑新产品的时候,分类信息也同样。
我们现在就创建整个应用,包括后台的数据库,使用 ASP.NET MVC3 只需要一到两分钟就可以。
Step 1: 创建新项目
我们通过创建一个新的 ASP.NET MVC3 项目开始,点击 文件 -> 新建项目,我们使用 Internet 项目模板,这将为我们的应用提供一个默认的起始模板。
当你在解决方案管理器中观察新创建的项目时,你将会看到 ASP.NET MVC3 更新后的工具增为我们的 ASP.NET MVC3 项目增加了一个新的程序集 EntityFramework 。
EntityFramework 程序集实现了 Entity Framework4.1 ,EF4.1 为 .NET 的数据访问提供了巨大的改进,包括 Code First。EF Code First 提供了完全优雅和干净的数据处理方式 ,使你不再需要设计器或者 XML 的映射文件。通过 ASP.NET MVC3 项目就可以简单的使用这个优点。
我们将使用 EF Code First 来实现项目的数据访问。
Step 2: 实现数据模型类
第一步,我们将创建两个类,Product 和 Category,我们应用程序的数据模型,我们在 Models 文件中中创建标准的 POCO “简单的老的 C# 对象” 。代码如下:
注意到上面的类是标准的 .NET 数据类型,不需要派生自任何基类,也不需要实现任何接口。
对于每个单独的属性,每个类有一个关联属性,例如,Product 类有一个名为 Category 的属性使开发人员可以获取产品所属的 Category ,而 Category 类中有一个名为 Products 的属性,使得开发人员可以获取分类的所有产品,EF Code First 可以自动管理这些关联(使用主外键关系),还可以在后台延迟加载数据。
Step 3: 使用 EF Code First 实现 StoreContext 类
现在,我们已经定义了两个模型类,下一步我们将要实现 DbContext 类,使用 EF Code First 需要使用这个类将模型对象映射到数据库中表,我们的实现如下所示:
我们使用 StoreContext 类映射我们的 Product 和 Category 与数据库的关系,它派生自 EF Code First 中的 DbContext,提供了两个属性关联到数据库中的表,对于我们的例子来说,使用默认的“约定胜于配置”方式,这意味着 Products 属性映射到数据库中的 Products 表,Categories 映射到数据库中的 Categories 表。在博文的后面,我还将讨论如何实现自定义的映射。
你可以将这个类加入到解决方案的任何位置,例如,可以放置在 \Models 文件夹中,或者放在一个独立的类库项目中,可能你需要在代码的前面增加对于命名空间 System.Data.Entity 的引用。DbContext 和 DbSet 定义在其中。
Step 4: 搭建 Categories 控制器的脚手架
我们已经创建了从数据库获取或者保存数据的所有内容。现在,我们创建一个 ASP.NET MVC 的控制器来实现对于分类数据的创建/编辑/删除/更新,从前的时候,你不得不手动写一个控制器来完成这些功能,包括你自己实现通过 EF Code First 访问数据代码,现在,ASP.NET MVC3 工具更新现在包括内建的脚手架支持帮助你自动完成这些工作。
搭建一个新的 Categories 控制器类,我们在 /Controllers 文件夹上右键,然后选择 增加 Add -> 控制器 Controller 上下文菜单。
然后,弹出增加控制器 Add Controller 的对话框,我们对创建的控制器命名为 CategoriesController,现在的对话框支持一个新的 脚手架节,允许我们使用内建的模板来搭建控制器。
我们选择 Controller With read/Write action and views, using Entity Framework 模板,这将使创建的控制器包括完整的 EF 增、删、改、查 代码。
在选择这个模板之后,我们选择控制器使用的模型类,来实现 CRUD 支持,这里是 Dategory 类,我们也选择 EF DbContext/ObjectContext 类来访问数据库,在这里,使用我们前面定义的 StoreContext 类。
当我们点击 Add 按钮的时候,Visual Studio 将会自动创建一个 CategoriesController 类,包括实现了Create、Edit、Details、Delete 和 Index Action 方法, 还有每一个 Action 相关的视图模板。
如果打开 CategoriesController.cs ,将会发现 Action 方法中已经实现了通过 EF 的数据访问支持。
我们已经实现了访问 Categories 数据的所有代码。
Step 5: 配置数据库的位置
在运行之前,我们的最后一步我们使用的数据库位置。EF Code First 允许使用现有的数据库,也允许使用目前还不存在的数据库,可以通过模型类来自动创建它。
没有连接串的情况
默认情况下,你甚至不需要配置连接串来指明数据库。如果没有指明,EF Code First 将在 SQL Express 中创建一个与你的 DbContext 同名的数据库,例如,我们现在将会在本地的 .\SQLExpress 中创建一个名为 ScaffoldingDemo.Models.StoreContes 的数据库。
通过连接串显式制定
你还可以在 web.config 中增加一个连接串的配置来显式指定,连接串的名字需要匹配 DbContext 类的名字,例如,在我们的应用中,DbContext 的名字是 StoreContext,默认情况下,EF 将会查找同名的连接串来决定数据库的位置。
下面是我们使用保存在 App_Data 文件夹中名为 Store.sdf 的嵌入的 SQL CE 数据库配置。
<configuration>
<connectionStrings>
<add name="StoreContext"
connectionString="Data Source=|DataDirectory|\Store.sdf"
providerName="System.Data.SqlServerCe.4.0" />
</connectionStrings>
</configuration>
Step 6: 运行应用
好啦!现在我们运行这个应用,导航到 /Categories ,这将会执行 CategoriesController 的 Index 方法,列出数据库中所有的分类,当前还没有分类。
点击 Create New 链接来创建一个新的分类,这会导航到 /Categories/Create ,这个 Action 提供了一个创建新分类的表单。
点击 Create 将会 Post 到 CategoriesController ,添加新的分类到数据库中,重复这个操作,我们可以创建多个不同的分类。
非常酷的一点在于,我们不需要写任何的控制器或者视图就可以完成!
脚手架自动生成了需要的代码,这提供了一个简单的起点,我们可以继续调整它来定制更多的功能。
Step 7: 关注数据库
我们现在配置程序使用嵌入式的数据库 SQL CE,当运行程序的时候,如果数据库还不存在,那么 EF 4.1 将会检测到这一点,然后自动创建它,基于我们前面定义的 Product 和 Category 类。
要想在解决方案中看到数据库,在解决方案管理器的上面点击刷新按钮,然后,EF 自动创建的 Store.sdf 将会出现在 App_Data 文件夹下。
你可以通过双击这个数据库,在服务器资源管理器中打开它,然后展开 Tables ,就可以看到刚刚创建的表。
注意 EF 创建的表基于 Product 和 Category 类,还根据类中属性的定义,自动创建了主键和两表之间的关联。
Step 8: 搭建 Product 控制器的脚手架
我们已经创建了 CategoriesController 来管理分类,下面我们创建 ProductsController 来管理产品。
就向前面一样,我们在 \Controller 文件夹上右键,选择 Add -> Controller 来创建 ProductsController,我们使用 EF 模板和 Product 模型类。
点击 Add 按钮之后,ProductsController 已经搭建完成,包括 CRUD 方法和相应的视图。
我们可以运行一下,导航到 /Products。
点击 Create New 来创建产品
很酷的是分类是一个下拉列表,而不是一个填写外键的文本框。
在 Visual Studio 中支持的脚手架很聪明地检测到关联的分类,EF 代码自动关联正确的分类。
在创建一些产品之后,访问 /Products 显示的效果如下。
注意分类信息是使用友好的名称显示出来,而不是一个外键值。